<commit_before>// Copyright (c) 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <assert.h>
#include <Windows.h>
#include <WinInet.h>

// Disable exception handler warnings.
#pragma warning( disable : 4530 )

#include <fstream>

#include "common/windows/string_utils-inl.h"

#include "common/windows/http_upload.h"

namespace google_airbag {

using std::ifstream;
using std::ios;

static const wchar_t kUserAgent[] = L"Airbag/1.0 (Windows)";

// Helper class which closes an internet handle when it goes away
class HTTPUpload::AutoInternetHandle {
 public:
  explicit AutoInternetHandle(HINTERNET handle) : handle_(handle) {}
  ~AutoInternetHandle() {
    if (handle_) {
      InternetCloseHandle(handle_);
    }
  }

  HINTERNET get() { return handle_; }

 private:
  HINTERNET handle_;
};

// static
bool HTTPUpload::SendRequest(const wstring &url,
                             const map<wstring, wstring> &parameters,
                             const wstring &upload_file,
                             const wstring &file_part_name) {
  // TODO(bryner): support non-ASCII parameter names
  if (!CheckParameters(parameters)) {
    return false;
  }

  // Break up the URL and make sure we can handle it
  wchar_t scheme[16], host[256], path[256];
  URL_COMPONENTS components;
  memset(&components, 0, sizeof(components));
  components.dwStructSize = sizeof(components);
  components.lpszScheme = scheme;
  components.dwSchemeLength = sizeof(scheme);
  components.lpszHostName = host;
  components.dwHostNameLength = sizeof(host);
  components.lpszUrlPath = path;
  components.dwUrlPathLength = sizeof(path);
  if (!InternetCrackUrl(url.c_str(), static_cast<DWORD>(url.size()),
                        0, &components)) {
    return false;
  }
  bool secure = false;
  if (wcscmp(scheme, L"https") == 0) {
    secure = true;
  } else if (wcscmp(scheme, L"http") != 0) {
    return false;
  }

  AutoInternetHandle internet(InternetOpen(kUserAgent,
                                           INTERNET_OPEN_TYPE_PRECONFIG,
                                           NULL,  // proxy name
                                           NULL,  // proxy bypass
                                           0));   // flags
  if (!internet.get()) {
    return false;
  }

  AutoInternetHandle connection(InternetConnect(internet.get(),
                                                host,
                                                components.nPort,
                                                NULL,    // user name
                                                NULL,    // password
                                                INTERNET_SERVICE_HTTP,
                                                0,       // flags
                                                NULL));  // context
  if (!connection.get()) {
    return false;
  }

  DWORD http_open_flags = secure ? INTERNET_FLAG_SECURE : 0;
  AutoInternetHandle request(HttpOpenRequest(connection.get(),
                                             L"POST",
                                             path,
                                             NULL,    // version
                                             NULL,    // referer
                                             NULL,    // agent type
                                             http_open_flags,
                                             NULL));  // context
  if (!request.get()) {
    return false;
  }

  wstring boundary = GenerateMultipartBoundary();
  wstring content_type_header = GenerateRequestHeader(boundary);
  HttpAddRequestHeaders(request.get(),
                        content_type_header.c_str(),
                        -1, HTTP_ADDREQ_FLAG_ADD);

  string request_body;
  GenerateRequestBody(parameters, upload_file,
                      file_part_name, boundary, &request_body);

  if (!HttpSendRequest(request.get(), NULL, 0,
                       const_cast<char *>(request_body.data()),
                       static_cast<DWORD>(request_body.size()))) {
    return false;
  }

  // The server indicates a successful upload with HTTP status 200.
  wchar_t http_status[4];
  DWORD http_status_size = sizeof(http_status);
  if (!HttpQueryInfo(request.get(), HTTP_QUERY_STATUS_CODE,
                     static_cast<LPVOID>(&http_status), &http_status_size,
                     0)) {
    return false;
  }

  return (wcscmp(http_status, L"200") == 0);
}

// static
wstring HTTPUpload::GenerateMultipartBoundary() {
  // The boundary has 27 '-' characters followed by 16 hex digits
  static const wchar_t kBoundaryPrefix[] = L"---------------------------";
  static const int kBoundaryLength = 27 + 16 + 1;

  // Generate some random numbers to fill out the boundary
  int r0 = rand();
  int r1 = rand();

  wchar_t temp[kBoundaryLength];
  WindowsStringUtils::safe_swprintf(temp, kBoundaryLength, L"%s%08X%08X",
                                    kBoundaryPrefix, r0, r1);
  return wstring(temp);
}

// static
wstring HTTPUpload::GenerateRequestHeader(const wstring &boundary) {
  wstring header = L"Content-Type: multipart/form-data; boundary=";
  header += boundary;
  return header;
}

// static
bool HTTPUpload::GenerateRequestBody(const map<wstring, wstring> &parameters,
                                     const wstring &upload_file,
                                     const wstring &file_part_name,
                                     const wstring &boundary,
                                     string *request_body) {
  vector<char> contents;
  GetFileContents(upload_file, &contents);
  if (contents.empty()) {
    return false;
  }

  string boundary_str = WideToUTF8(boundary);
  if (boundary_str.empty()) {
    return false;
  }

  request_body->clear();

  // Append each of the parameter pairs as a form-data part
  for (map<wstring, wstring>::const_iterator pos = parameters.begin();
       pos != parameters.end(); ++pos) {
    request_body->append("--" + boundary_str + "\r\n");
    request_body->append("Content-Disposition: form-data; name=\"" +
                         WideToUTF8(pos->first) + "\"\r\n\r\n" +
                         WideToUTF8(pos->second) + "\r\n");
  }

  // Now append the upload file as a binary (octet-stream) part
  string filename_utf8 = WideToUTF8(upload_file);
  if (filename_utf8.empty()) {
    return false;
  }

  string file_part_name_utf8 = WideToUTF8(file_part_name);
  if (file_part_name_utf8.empty()) {
    return false;
  }

  request_body->append("--" + boundary_str + "\r\n");
  request_body->append("Content-Disposition: form-data; "
                       "name=\"" + file_part_name_utf8 + "\"; "
                       "filename=\"" + filename_utf8 + "\"\r\n");
  request_body->append("Content-Type: application/octet-stream\r\n");
  request_body->append("\r\n");

  request_body->append(&(contents[0]), contents.size());
  request_body->append("\r\n");
  request_body->append("--" + boundary_str + "--\r\n");
  return true;
}

// static
void HTTPUpload::GetFileContents(const wstring &filename,
                                 vector<char> *contents) {
  // The "open" method on pre-MSVC8 ifstream implementations doesn't accept a
  // wchar_t* filename, so use _wfopen directly in that case.  For VC8 and
  // later, _wfopen has been deprecated in favor of _wfopen_s, which does
  // not exist in earlier versions, so let the ifstream open the file itself.
#if _MSC_VER >= 1400  // MSVC 2005/8
  ifstream file;
  file.open(filename.c_str(), ios::binary);
#else  // _MSC_VER >= 1400
  ifstream file(_wfopen(filename.c_str(), L"rb"));
#endif  // _MSC_VER >= 1400
  if (file.is_open()) {
    file.seekg(0, ios::end);
    int length = file.tellg();
    contents->resize(length);
    file.seekg(0, ios::beg);
    file.read(&((*contents)[0]), length);
    file.close();
  } else {
    contents->clear();
  }
}

// static
string HTTPUpload::WideToUTF8(const wstring &wide) {
  if (wide.length() == 0) {
    return string();
  }

  // compute the length of the buffer we'll need
  int charcount = WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), -1,
                                      NULL, 0, NULL, NULL);
  if (charcount == 0) {
    return string();
  }

  // convert
  char *buf = new char[charcount];
  WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), -1, buf, charcount,
                      NULL, NULL);

  string result(buf);
  delete[] buf;
  return result;
}

// static
bool HTTPUpload::CheckParameters(const map<wstring, wstring> &parameters) {
  for (map<wstring, wstring>::const_iterator pos = parameters.begin();
       pos != parameters.end(); ++pos) {
    const wstring &str = pos->first;
    if (str.size() == 0) {
      return false;  // disallow empty parameter names
    }
    for (unsigned int i = 0; i < str.size(); ++i) {
      wchar_t c = str[i];
      if (c < 32 || c == '"' || c > 127) {
        return false;
      }
    }
  }
  return true;
}

}  // namespace google_airbag
<commit_msg>Fix a crash when attempting to upload a zero-length dump file (#83) r=mmentovai<commit_after>// Copyright (c) 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <assert.h>
#include <Windows.h>
#include <WinInet.h>

// Disable exception handler warnings.
#pragma warning( disable : 4530 )

#include <fstream>

#include "common/windows/string_utils-inl.h"

#include "common/windows/http_upload.h"

namespace google_airbag {

using std::ifstream;
using std::ios;

static const wchar_t kUserAgent[] = L"Airbag/1.0 (Windows)";

// Helper class which closes an internet handle when it goes away
class HTTPUpload::AutoInternetHandle {
 public:
  explicit AutoInternetHandle(HINTERNET handle) : handle_(handle) {}
  ~AutoInternetHandle() {
    if (handle_) {
      InternetCloseHandle(handle_);
    }
  }

  HINTERNET get() { return handle_; }

 private:
  HINTERNET handle_;
};

// static
bool HTTPUpload::SendRequest(const wstring &url,
                             const map<wstring, wstring> &parameters,
                             const wstring &upload_file,
                             const wstring &file_part_name) {
  // TODO(bryner): support non-ASCII parameter names
  if (!CheckParameters(parameters)) {
    return false;
  }

  // Break up the URL and make sure we can handle it
  wchar_t scheme[16], host[256], path[256];
  URL_COMPONENTS components;
  memset(&components, 0, sizeof(components));
  components.dwStructSize = sizeof(components);
  components.lpszScheme = scheme;
  components.dwSchemeLength = sizeof(scheme);
  components.lpszHostName = host;
  components.dwHostNameLength = sizeof(host);
  components.lpszUrlPath = path;
  components.dwUrlPathLength = sizeof(path);
  if (!InternetCrackUrl(url.c_str(), static_cast<DWORD>(url.size()),
                        0, &components)) {
    return false;
  }
  bool secure = false;
  if (wcscmp(scheme, L"https") == 0) {
    secure = true;
  } else if (wcscmp(scheme, L"http") != 0) {
    return false;
  }

  AutoInternetHandle internet(InternetOpen(kUserAgent,
                                           INTERNET_OPEN_TYPE_PRECONFIG,
                                           NULL,  // proxy name
                                           NULL,  // proxy bypass
                                           0));   // flags
  if (!internet.get()) {
    return false;
  }

  AutoInternetHandle connection(InternetConnect(internet.get(),
                                                host,
                                                components.nPort,
                                                NULL,    // user name
                                                NULL,    // password
                                                INTERNET_SERVICE_HTTP,
                                                0,       // flags
                                                NULL));  // context
  if (!connection.get()) {
    return false;
  }

  DWORD http_open_flags = secure ? INTERNET_FLAG_SECURE : 0;
  AutoInternetHandle request(HttpOpenRequest(connection.get(),
                                             L"POST",
                                             path,
                                             NULL,    // version
                                             NULL,    // referer
                                             NULL,    // agent type
                                             http_open_flags,
                                             NULL));  // context
  if (!request.get()) {
    return false;
  }

  wstring boundary = GenerateMultipartBoundary();
  wstring content_type_header = GenerateRequestHeader(boundary);
  HttpAddRequestHeaders(request.get(),
                        content_type_header.c_str(),
                        -1, HTTP_ADDREQ_FLAG_ADD);

  string request_body;
  GenerateRequestBody(parameters, upload_file,
                      file_part_name, boundary, &request_body);

  if (!HttpSendRequest(request.get(), NULL, 0,
                       const_cast<char *>(request_body.data()),
                       static_cast<DWORD>(request_body.size()))) {
    return false;
  }

  // The server indicates a successful upload with HTTP status 200.
  wchar_t http_status[4];
  DWORD http_status_size = sizeof(http_status);
  if (!HttpQueryInfo(request.get(), HTTP_QUERY_STATUS_CODE,
                     static_cast<LPVOID>(&http_status), &http_status_size,
                     0)) {
    return false;
  }

  return (wcscmp(http_status, L"200") == 0);
}

// static
wstring HTTPUpload::GenerateMultipartBoundary() {
  // The boundary has 27 '-' characters followed by 16 hex digits
  static const wchar_t kBoundaryPrefix[] = L"---------------------------";
  static const int kBoundaryLength = 27 + 16 + 1;

  // Generate some random numbers to fill out the boundary
  int r0 = rand();
  int r1 = rand();

  wchar_t temp[kBoundaryLength];
  WindowsStringUtils::safe_swprintf(temp, kBoundaryLength, L"%s%08X%08X",
                                    kBoundaryPrefix, r0, r1);
  return wstring(temp);
}

// static
wstring HTTPUpload::GenerateRequestHeader(const wstring &boundary) {
  wstring header = L"Content-Type: multipart/form-data; boundary=";
  header += boundary;
  return header;
}

// static
bool HTTPUpload::GenerateRequestBody(const map<wstring, wstring> &parameters,
                                     const wstring &upload_file,
                                     const wstring &file_part_name,
                                     const wstring &boundary,
                                     string *request_body) {
  vector<char> contents;
  GetFileContents(upload_file, &contents);
  if (contents.empty()) {
    return false;
  }

  string boundary_str = WideToUTF8(boundary);
  if (boundary_str.empty()) {
    return false;
  }

  request_body->clear();

  // Append each of the parameter pairs as a form-data part
  for (map<wstring, wstring>::const_iterator pos = parameters.begin();
       pos != parameters.end(); ++pos) {
    request_body->append("--" + boundary_str + "\r\n");
    request_body->append("Content-Disposition: form-data; name=\"" +
                         WideToUTF8(pos->first) + "\"\r\n\r\n" +
                         WideToUTF8(pos->second) + "\r\n");
  }

  // Now append the upload file as a binary (octet-stream) part
  string filename_utf8 = WideToUTF8(upload_file);
  if (filename_utf8.empty()) {
    return false;
  }

  string file_part_name_utf8 = WideToUTF8(file_part_name);
  if (file_part_name_utf8.empty()) {
    return false;
  }

  request_body->append("--" + boundary_str + "\r\n");
  request_body->append("Content-Disposition: form-data; "
                       "name=\"" + file_part_name_utf8 + "\"; "
                       "filename=\"" + filename_utf8 + "\"\r\n");
  request_body->append("Content-Type: application/octet-stream\r\n");
  request_body->append("\r\n");

  if (!contents.empty()) {
      request_body->append(&(contents[0]), contents.size());
  }
  request_body->append("\r\n");
  request_body->append("--" + boundary_str + "--\r\n");
  return true;
}

// static
void HTTPUpload::GetFileContents(const wstring &filename,
                                 vector<char> *contents) {
  // The "open" method on pre-MSVC8 ifstream implementations doesn't accept a
  // wchar_t* filename, so use _wfopen directly in that case.  For VC8 and
  // later, _wfopen has been deprecated in favor of _wfopen_s, which does
  // not exist in earlier versions, so let the ifstream open the file itself.
#if _MSC_VER >= 1400  // MSVC 2005/8
  ifstream file;
  file.open(filename.c_str(), ios::binary);
#else  // _MSC_VER >= 1400
  ifstream file(_wfopen(filename.c_str(), L"rb"));
#endif  // _MSC_VER >= 1400
  if (file.is_open()) {
    file.seekg(0, ios::end);
    int length = file.tellg();
    contents->resize(length);
    if (length != 0) {
        file.seekg(0, ios::beg);
        file.read(&((*contents)[0]), length);
    }
    file.close();
  } else {
    contents->clear();
  }
}

// static
string HTTPUpload::WideToUTF8(const wstring &wide) {
  if (wide.length() == 0) {
    return string();
  }

  // compute the length of the buffer we'll need
  int charcount = WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), -1,
                                      NULL, 0, NULL, NULL);
  if (charcount == 0) {
    return string();
  }

  // convert
  char *buf = new char[charcount];
  WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), -1, buf, charcount,
                      NULL, NULL);

  string result(buf);
  delete[] buf;
  return result;
}

// static
bool HTTPUpload::CheckParameters(const map<wstring, wstring> &parameters) {
  for (map<wstring, wstring>::const_iterator pos = parameters.begin();
       pos != parameters.end(); ++pos) {
    const wstring &str = pos->first;
    if (str.size() == 0) {
      return false;  // disallow empty parameter names
    }
    for (unsigned int i = 0; i < str.size(); ++i) {
      wchar_t c = str[i];
      if (c < 32 || c == '"' || c > 127) {
        return false;
      }
    }
  }
  return true;
}

}  // namespace google_airbag
<|endoftext|>


<commit_before>/**
 * Copyright (C)  2006  Brad Hards <bradh@frogmouth.net>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <QtCrypto>
#include <QtTest/QtTest>

class TLSUnitTest : public QObject
{
    Q_OBJECT

private slots:
    void initTestCase();
    void cleanupTestCase();
    void testCipherList();
private:
    QCA::Initializer* m_init;
};

void TLSUnitTest::initTestCase()
{
    m_init = new QCA::Initializer;
#include "../fixpaths.include"
}

void TLSUnitTest::cleanupTestCase()
{
    delete m_init;
}

void TLSUnitTest::testCipherList()
{
    if(!QCA::isSupported("tls", "qca-openssl"))
	QWARN("TLS not supported for qca-openssl");
    else {
	QStringList cipherList = QCA::TLS::supportedCipherSuites(QCA::TLS::TLS_v1, "qca-openssl");
	QVERIFY( cipherList.contains("TLS_DHE_RSA_WITH_AES_256_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_DHE_DSS_WITH_AES_256_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_RSA_WITH_AES_256_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_RSA_WITH_3DES_EDE_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_DHE_RSA_WITH_AES_128_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_DHE_DSS_WITH_AES_128_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_RSA_WITH_AES_128_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_CK_DHE_DSS_WITH_RC4_128_SHA") );
	QVERIFY( cipherList.contains("TLS_RSA_WITH_RC4_128_SHA") );
	QVERIFY( cipherList.contains("TLS_RSA_WITH_RC4_128_MD5") );
	QVERIFY( cipherList.contains("TLS_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5") );
	QVERIFY( cipherList.contains("TLS_DHE_RSA_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_DHE_DSS_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_RSA_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA") );
	QVERIFY( cipherList.contains("TLS_CK_RSA_EXPORT1024_WITH_RC4_56_SHA") );
	QVERIFY( cipherList.contains("TLS_CK_RSA_EXPORT1024_WITH_RC4_56_MD5") );
	QVERIFY( cipherList.contains("TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_RSA_EXPORT_WITH_DES40_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5") );
	QVERIFY( cipherList.contains("TLS_RSA_EXPORT_WITH_RC4_40_MD5") );

	cipherList = QCA::TLS::supportedCipherSuites(QCA::TLS::SSL_v3, "qca-openssl");
	QVERIFY( cipherList.contains("SSL_DHE_RSA_WITH_AES_256_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_DHE_DSS_WITH_AES_256_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_RSA_WITH_AES_256_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_RSA_WITH_3DES_EDE_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_DHE_RSA_WITH_AES_128_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_DHE_DSS_WITH_AES_128_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_RSA_WITH_AES_128_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_CK_DHE_DSS_WITH_RC4_128_SHA") );
	QVERIFY( cipherList.contains("SSL_RSA_WITH_RC4_128_SHA") );
	QVERIFY( cipherList.contains("SSL_RSA_WITH_RC4_128_MD5") );
	QVERIFY( cipherList.contains("SSL_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5") );
	QVERIFY( cipherList.contains("SSL_DHE_RSA_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_DHE_DSS_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_RSA_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA") );
	QVERIFY( cipherList.contains("SSL_CK_RSA_EXPORT1024_WITH_RC4_56_SHA") );
	QVERIFY( cipherList.contains("SSL_CK_RSA_EXPORT1024_WITH_RC4_56_MD5") );
	QVERIFY( cipherList.contains("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5") );
	QVERIFY( cipherList.contains("SSL_RSA_EXPORT_WITH_RC4_40_MD5") );

	cipherList = QCA::TLS::supportedCipherSuites(QCA::TLS::SSL_v2, "qca-openssl");
	QVERIFY( cipherList.contains("SSL_CK_DES_192_EDE3_CBC_WITH_MD5") );
	QVERIFY( cipherList.contains("SSL_CK_RC4_128_EXPORT40_WITH_MD5") );
	QVERIFY( cipherList.contains("SSL_CK_RC2_128_CBC_WITH_MD5") );
	QVERIFY( cipherList.contains("SSL_CK_RC4_128_WITH_MD5") );
	QVERIFY( cipherList.contains("SSL_CK_RC4_64_WITH_MD5") );
	QVERIFY( cipherList.contains("SSL_CK_DES_64_CBC_WITH_MD5") );
	QVERIFY( cipherList.contains("SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5") );
	QVERIFY( cipherList.contains("SSL_CK_RC4_128_EXPORT40_WITH_MD5") );
    }
}

QTEST_MAIN(TLSUnitTest)

#include "tlsunittest.moc"
<commit_msg>update based on api changes<commit_after>/**
 * Copyright (C)  2006  Brad Hards <bradh@frogmouth.net>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <QtCrypto>
#include <QtTest/QtTest>

class TLSUnitTest : public QObject
{
    Q_OBJECT

private slots:
    void initTestCase();
    void cleanupTestCase();
    void testCipherList();
private:
    QCA::Initializer* m_init;
};

void TLSUnitTest::initTestCase()
{
    m_init = new QCA::Initializer;
#include "../fixpaths.include"
}

void TLSUnitTest::cleanupTestCase()
{
    delete m_init;
}

void TLSUnitTest::testCipherList()
{
    if(!QCA::isSupported("tls", "qca-openssl"))
	QWARN("TLS not supported for qca-openssl");
    else {
	QCA::TLS *tls = new QCA::TLS(QCA::TLS::Stream, 0, "qca-openssl");
	QStringList cipherList = tls->supportedCipherSuites(QCA::TLS::TLS_v1);
	QVERIFY( cipherList.contains("TLS_DHE_RSA_WITH_AES_256_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_DHE_DSS_WITH_AES_256_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_RSA_WITH_AES_256_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_RSA_WITH_3DES_EDE_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_DHE_RSA_WITH_AES_128_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_DHE_DSS_WITH_AES_128_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_RSA_WITH_AES_128_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_CK_DHE_DSS_WITH_RC4_128_SHA") );
	QVERIFY( cipherList.contains("TLS_RSA_WITH_RC4_128_SHA") );
	QVERIFY( cipherList.contains("TLS_RSA_WITH_RC4_128_MD5") );
	QVERIFY( cipherList.contains("TLS_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5") );
	QVERIFY( cipherList.contains("TLS_DHE_RSA_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_DHE_DSS_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_RSA_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA") );
	QVERIFY( cipherList.contains("TLS_CK_RSA_EXPORT1024_WITH_RC4_56_SHA") );
	QVERIFY( cipherList.contains("TLS_CK_RSA_EXPORT1024_WITH_RC4_56_MD5") );
	QVERIFY( cipherList.contains("TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_RSA_EXPORT_WITH_DES40_CBC_SHA") );
	QVERIFY( cipherList.contains("TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5") );
	QVERIFY( cipherList.contains("TLS_RSA_EXPORT_WITH_RC4_40_MD5") );

	cipherList = tls->supportedCipherSuites(QCA::TLS::SSL_v3);
	QVERIFY( cipherList.contains("SSL_DHE_RSA_WITH_AES_256_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_DHE_DSS_WITH_AES_256_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_RSA_WITH_AES_256_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_RSA_WITH_3DES_EDE_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_DHE_RSA_WITH_AES_128_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_DHE_DSS_WITH_AES_128_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_RSA_WITH_AES_128_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_CK_DHE_DSS_WITH_RC4_128_SHA") );
	QVERIFY( cipherList.contains("SSL_RSA_WITH_RC4_128_SHA") );
	QVERIFY( cipherList.contains("SSL_RSA_WITH_RC4_128_MD5") );
	QVERIFY( cipherList.contains("SSL_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5") );
	QVERIFY( cipherList.contains("SSL_DHE_RSA_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_DHE_DSS_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_RSA_WITH_DES_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA") );
	QVERIFY( cipherList.contains("SSL_CK_RSA_EXPORT1024_WITH_RC4_56_SHA") );
	QVERIFY( cipherList.contains("SSL_CK_RSA_EXPORT1024_WITH_RC4_56_MD5") );
	QVERIFY( cipherList.contains("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA") );
	QVERIFY( cipherList.contains("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5") );
	QVERIFY( cipherList.contains("SSL_RSA_EXPORT_WITH_RC4_40_MD5") );

	cipherList = tls->supportedCipherSuites(QCA::TLS::SSL_v2);
	QVERIFY( cipherList.contains("SSL_CK_DES_192_EDE3_CBC_WITH_MD5") );
	QVERIFY( cipherList.contains("SSL_CK_RC4_128_EXPORT40_WITH_MD5") );
	QVERIFY( cipherList.contains("SSL_CK_RC2_128_CBC_WITH_MD5") );
	QVERIFY( cipherList.contains("SSL_CK_RC4_128_WITH_MD5") );
	QVERIFY( cipherList.contains("SSL_CK_RC4_64_WITH_MD5") );
	QVERIFY( cipherList.contains("SSL_CK_DES_64_CBC_WITH_MD5") );
	QVERIFY( cipherList.contains("SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5") );
	QVERIFY( cipherList.contains("SSL_CK_RC4_128_EXPORT40_WITH_MD5") );
    }
}

QTEST_MAIN(TLSUnitTest)

#include "tlsunittest.moc"
<|endoftext|>


<commit_before>/**************************************************************************************/
/*                                                                                */
/*  Visualization Library                                                             */
/*  http://www.visualizationlibrary.com                                               */
/*                                                                                */
/*  Copyright (c) 2005-2010, Michele Bosi                                             */
/*  All rights reserved.                                                              */
/*                                                                                */
/*  Redistribution and use in source and binary forms, with or without modification,  */
/*  are permitted provided that the following conditions are met:                     */
/*                                                                                */
/*  - Redistributions of source code must retain the above copyright notice, this     */
/*  list of conditions and the following disclaimer.                                  */
/*                                                                                */
/*  - Redistributions in binary form must reproduce the above copyright notice, this  */
/*  list of conditions and the following disclaimer in the documentation and/or       */
/*  other materials provided with the distribution.                                   */
/*                                                                                */
/*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
/*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
/*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
/*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
/*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
/*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
/*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
/*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
/*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
/*                                                                                */
/**************************************************************************************/

#include "BaseDemo.hpp"
#include "vl/EdgeExtractor.hpp"
#include "vl/EdgeRenderer.hpp"
#include "vl/LoadWriterManager.hpp"

class App_EdgeRendering: public BaseDemo
{
public:
  void setupScene()
  {
    // setup common states
    vl::ref<vl::Light> camera_light = new vl::Light(0);
    vl::ref<vl::EnableSet> enables = new vl::EnableSet;
    enables->enable(vl::EN_DEPTH_TEST);
    enables->enable(vl::EN_LIGHTING);

    // red material fx
    vl::ref<vl::Effect> red_fx = new vl::Effect;
    red_fx->shader()->setEnableSet(enables.get());
    red_fx->shader()->gocMaterial()->setDiffuse(vlut::red);
    red_fx->shader()->setRenderState(camera_light.get());

    // green material fx
    vl::ref<vl::Effect> green_fx = new vl::Effect;
    green_fx->shader()->setEnableSet(enables.get());
    green_fx->shader()->gocMaterial()->setDiffuse(vlut::green);
    green_fx->shader()->setRenderState(camera_light.get());

    // blue material fx
    vl::ref<vl::Effect> yellow_fx = new vl::Effect;
    yellow_fx->shader()->setEnableSet(enables.get());
    yellow_fx->shader()->gocMaterial()->setDiffuse(vlut::yellow);
    yellow_fx->shader()->setRenderState(camera_light.get());

    // add box, cylinder, cone actors to the scene
    vl::ref<vl::Geometry> geom1 = vlut::makeBox     (vl::vec3(-7,0,0),5,5,5);
    vl::ref<vl::Geometry> geom2 = vlut::makeCylinder(vl::vec3(0,0,0), 5,5, 10,2, true, true);
    vl::ref<vl::Geometry> geom3 = vlut::makeCone    (vl::vec3(+7,0,0),5,5, 20, true);

    // needed since we enabled the lighting
    geom1->computeNormals();
    geom2->computeNormals();
    geom3->computeNormals();

    // add the actors to the scene
    sceneManager()->tree()->addActor( geom1.get(), red_fx.get(),    mRendering->transform() );
    sceneManager()->tree()->addActor( geom2.get(), green_fx.get(),  mRendering->transform() );
    sceneManager()->tree()->addActor( geom3.get(), yellow_fx.get(), mRendering->transform() );
  }

  void initEvent()
  {
    BaseDemo::initEvent();

    // retrieve the default rendering
    mRendering = (vl::VisualizationLibrary::rendering()->as<vl::Rendering>());
    // retrieve the default renderer, which we'll use as the solid-renderer
    mSolidRenderer = mRendering->renderer();

    // create our EdgeRenderer
    mEdgeRenderer = new vl::EdgeRenderer;
    // we set the clear flags to be vl::CF_CLEAR_DEPTH (by default is set to CF_CLEAR_COLOR_DEPTH) because
    // when the wireframe rendering starts we want to preserve the color-buffer as generated by the solid
    // rendering but we want to clear the Z-buffer as it is needed by the hidden-line-removal algorithm
    // implemented by vl::EdgeRenderer.
    mEdgeRenderer->setClearFlags(vl::CF_CLEAR_DEPTH);
    // target the same opengl window
    mEdgeRenderer->setRenderTarget(mSolidRenderer->renderTarget());
    // enqueue the EdgeRenderer in the rendering, will be executed after mSolidRenderer
    mRendering->renderers().push_back( mEdgeRenderer.get() );

    // hidden line and crease options
    mEdgeRenderer->setShowHiddenLines(true);
    mEdgeRenderer->setShowCreases(true);
    mEdgeRenderer->setCreaseAngle(35.0f);

    // style options
    mEdgeRenderer->setLineWidth(2.0f);
    mEdgeRenderer->setSmoothLines(true);
    mEdgeRenderer->setDefaultLineColor(vlut::black);

    // fills mSceneManager with a few actors.
    // the beauty of this system is that you setup your actors ony once in a single scene managers and
    // they will be rendered twice, first using a normal renderer and then using the wireframe renderer.
    setupScene();
  }

  // user controls:
  // '1' = edge rendering off.
  // '2' = edge rendering on: silhouette only.
  // '3' = edge rendering on: silhouette + creases.
  // '4' = edge rendering on: silhouette + creases + hidden lines.
  // '5' = hidden line removal wireframe: silhouette + creases.
  // '6' = hidden line removal wireframe: silhouette + creases + hidden lines.
  void keyPressEvent(unsigned short ch, vl::EKey key)
  {
    BaseDemo::keyPressEvent(ch, key);

    if (ch == '1')
    {
      mSolidRenderer->setEnableMask(0xFFFFFFFF);
      mEdgeRenderer->setEnableMask(0);
      vl::Log::print("Edge rendering disabled.\n");
    }
    else
    if (ch == '2')
    {
      mSolidRenderer->setEnableMask(0xFFFFFFFF);
      // preserve color buffer, clear depth buffer
      mEdgeRenderer->setClearFlags(vl::CF_CLEAR_DEPTH);
      mEdgeRenderer->setEnableMask(0xFFFFFFFF);
      mEdgeRenderer->setShowCreases(false);
      mEdgeRenderer->setShowHiddenLines(false);
      vl::Log::print("Edge rendering enabled. Creases = off, hidden lines = off.\n");
    }
    else
    if (ch == '3')
    {
      mSolidRenderer->setEnableMask(0xFFFFFFFF);
      // preserve color buffer, clear depth buffer
      mEdgeRenderer->setClearFlags(vl::CF_CLEAR_DEPTH);
      mEdgeRenderer->setEnableMask(0xFFFFFFFF);
      mEdgeRenderer->setShowCreases(true);
      mEdgeRenderer->setShowHiddenLines(false);
      vl::Log::print("Edge rendering enabled. Creases = on, hidden lines = off.\n");
    }
    else
    if (ch == '4')
    {
      mSolidRenderer->setEnableMask(0xFFFFFFFF);
      // preserve color buffer, clear depth buffer
      mEdgeRenderer->setClearFlags(vl::CF_CLEAR_DEPTH);
      mEdgeRenderer->setEnableMask(0xFFFFFFFF);
      mEdgeRenderer->setShowCreases(true);
      mEdgeRenderer->setShowHiddenLines(true);
      vl::Log::print("Edge rendering enabled. Creases = on, hidden lines = on.\n");
    }
    else
    if (ch == '5')
    {
      mSolidRenderer->setEnableMask(0);
      // clear color and depth buffer
      mEdgeRenderer->setClearFlags(vl::CF_CLEAR_COLOR_DEPTH);
      mEdgeRenderer->setEnableMask(0xFFFFFFFF);
      mEdgeRenderer->setShowCreases(true);
      mEdgeRenderer->setShowHiddenLines(false);
      vl::Log::print("Hidden line removal wireframe enabled. Creases = on, hidden lines = off.\n");
    }
    if (ch == '6')
    {
      mSolidRenderer->setEnableMask(0);
      // clear color and depth buffer
      mEdgeRenderer->setClearFlags(vl::CF_CLEAR_COLOR_DEPTH);
      mEdgeRenderer->setEnableMask(0xFFFFFFFF);
      mEdgeRenderer->setShowCreases(true);
      mEdgeRenderer->setShowHiddenLines(true);
      vl::Log::print("Hidden line removal wireframe enabled. Creases = on, hidden lines = on.\n");
    }
  }

  void resizeEvent(int w, int h)
  {
    vl::Camera* camera = mRendering->camera();
    camera->viewport()->setWidth ( w );
    camera->viewport()->setHeight( h );
    camera->setProjectionAsPerspective();
  }

  void loadModel(const std::vector<vl::String>& files)
  {
    // resets the scene
    mSceneManager->tree()->actors()->clear();
    // resets the EdgeRenderer cache
    mEdgeRenderer->clearCache();

    for(unsigned int i=0; i<files.size(); ++i)
    {
      vl::ref<vl::ResourceDatabase> resource_db = vl::loadResource(files[i],true);

      if (!resource_db || resource_db->count<vl::Actor>() == 0)
      {
        vl::Log::error("No data found.\n");
        continue;
      }

      std::vector< vl::ref<vl::Actor> > actors;
      resource_db->get<vl::Actor>(actors);
      for(unsigned i=0; i<actors.size(); ++i)
      {
        vl::ref<vl::Actor> actor = actors[i].get();
        // define a reasonable Shader
        actor->effect()->shader()->setRenderState( new vl::Light(0) );
        actor->effect()->shader()->enable(vl::EN_DEPTH_TEST);
        actor->effect()->shader()->enable(vl::EN_LIGHTING);
        actor->effect()->shader()->gocLightModel()->setTwoSide(true);
        // add the actor to the scene
        mSceneManager->tree()->addActor( actor.get() );
      }
    }

    // position the camera to nicely see the objects in the scene
    trackball()->adjustView( mSceneManager.get(), vl::vec3(0,0,1)/*direction*/, vl::vec3(0,1,0)/*up*/, 1.0f/*bias*/ );
  }

  // laod the files dropped in the window
  void fileDroppedEvent(const std::vector<vl::String>& files) { loadModel(files); }

protected:
  vl::ref< vl::Renderer > mSolidRenderer;
  vl::ref< vl::EdgeRenderer > mEdgeRenderer;
  vl::ref<vl::Rendering> mRendering;
  vl::ref<vl::SceneManagerActorTree> mSceneManager;
};

// Have fun!
<commit_msg>code cosmetics.<commit_after>/**************************************************************************************/
/*                                                                                */
/*  Visualization Library                                                             */
/*  http://www.visualizationlibrary.com                                               */
/*                                                                                */
/*  Copyright (c) 2005-2010, Michele Bosi                                             */
/*  All rights reserved.                                                              */
/*                                                                                */
/*  Redistribution and use in source and binary forms, with or without modification,  */
/*  are permitted provided that the following conditions are met:                     */
/*                                                                                */
/*  - Redistributions of source code must retain the above copyright notice, this     */
/*  list of conditions and the following disclaimer.                                  */
/*                                                                                */
/*  - Redistributions in binary form must reproduce the above copyright notice, this  */
/*  list of conditions and the following disclaimer in the documentation and/or       */
/*  other materials provided with the distribution.                                   */
/*                                                                                */
/*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
/*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
/*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
/*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
/*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
/*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
/*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
/*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
/*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
/*                                                                                */
/**************************************************************************************/

#include "BaseDemo.hpp"
#include "vl/EdgeExtractor.hpp"
#include "vl/EdgeRenderer.hpp"
#include "vl/LoadWriterManager.hpp"

class App_EdgeRendering: public BaseDemo
{
public:
  void initEvent()
  {
    BaseDemo::initEvent();

    // retrieve the default rendering
    mRendering = (vl::VisualizationLibrary::rendering()->as<vl::Rendering>());
    // retrieve the default renderer, which we'll use as the solid-renderer
    mSolidRenderer = mRendering->renderer();

    // create our EdgeRenderer
    mEdgeRenderer = new vl::EdgeRenderer;
    // we set the clear flags to be vl::CF_CLEAR_DEPTH (by default is set to CF_CLEAR_COLOR_DEPTH) because
    // when the wireframe rendering starts we want to preserve the color-buffer as generated by the solid
    // rendering but we want to clear the Z-buffer as it is needed by the hidden-line-removal algorithm
    // implemented by vl::EdgeRenderer.
    mEdgeRenderer->setClearFlags(vl::CF_CLEAR_DEPTH);
    // target the same opengl window
    mEdgeRenderer->setRenderTarget(mSolidRenderer->renderTarget());
    // enqueue the EdgeRenderer in the rendering, will be executed after mSolidRenderer
    mRendering->renderers().push_back( mEdgeRenderer.get() );

    // hidden line and crease options
    mEdgeRenderer->setShowHiddenLines(true);
    mEdgeRenderer->setShowCreases(true);
    mEdgeRenderer->setCreaseAngle(35.0f);

    // style options
    mEdgeRenderer->setLineWidth(2.0f);
    mEdgeRenderer->setSmoothLines(true);
    mEdgeRenderer->setDefaultLineColor(vlut::black);

    // fills mSceneManager with a few actors.
    // the beauty of this system is that you setup your actors ony once in a single scene managers and
    // they will be rendered twice, first using a normal renderer and then using the wireframe renderer.
    setupScene();
  }

  // populates the scene
  void setupScene()
  {
    // setup common states
    vl::ref<vl::Light> camera_light = new vl::Light(0);
    vl::ref<vl::EnableSet> enables = new vl::EnableSet;
    enables->enable(vl::EN_DEPTH_TEST);
    enables->enable(vl::EN_LIGHTING);

    // red material fx
    vl::ref<vl::Effect> red_fx = new vl::Effect;
    red_fx->shader()->setEnableSet(enables.get());
    red_fx->shader()->gocMaterial()->setDiffuse(vlut::red);
    red_fx->shader()->setRenderState(camera_light.get());

    // green material fx
    vl::ref<vl::Effect> green_fx = new vl::Effect;
    green_fx->shader()->setEnableSet(enables.get());
    green_fx->shader()->gocMaterial()->setDiffuse(vlut::green);
    green_fx->shader()->setRenderState(camera_light.get());

    // blue material fx
    vl::ref<vl::Effect> yellow_fx = new vl::Effect;
    yellow_fx->shader()->setEnableSet(enables.get());
    yellow_fx->shader()->gocMaterial()->setDiffuse(vlut::yellow);
    yellow_fx->shader()->setRenderState(camera_light.get());

    // add box, cylinder, cone actors to the scene
    vl::ref<vl::Geometry> geom1 = vlut::makeBox     (vl::vec3(-7,0,0),5,5,5);
    vl::ref<vl::Geometry> geom2 = vlut::makeCylinder(vl::vec3(0,0,0), 5,5, 10,2, true, true);
    vl::ref<vl::Geometry> geom3 = vlut::makeCone    (vl::vec3(+7,0,0),5,5, 20, true);

    // needed since we enabled the lighting
    geom1->computeNormals();
    geom2->computeNormals();
    geom3->computeNormals();

    // add the actors to the scene
    sceneManager()->tree()->addActor( geom1.get(), red_fx.get(),    mRendering->transform() );
    sceneManager()->tree()->addActor( geom2.get(), green_fx.get(),  mRendering->transform() );
    sceneManager()->tree()->addActor( geom3.get(), yellow_fx.get(), mRendering->transform() );
  }

  // user controls:
  // '1' = edge rendering off.
  // '2' = edge rendering on: silhouette only.
  // '3' = edge rendering on: silhouette + creases.
  // '4' = edge rendering on: silhouette + creases + hidden lines.
  // '5' = hidden line removal wireframe: silhouette + creases.
  // '6' = hidden line removal wireframe: silhouette + creases + hidden lines.
  void keyPressEvent(unsigned short ch, vl::EKey key)
  {
    BaseDemo::keyPressEvent(ch, key);

    if (ch == '1')
    {
      mSolidRenderer->setEnableMask(0xFFFFFFFF);
      mEdgeRenderer->setEnableMask(0);
      vl::Log::print("Edge rendering disabled.\n");
    }
    else
    if (ch == '2')
    {
      mSolidRenderer->setEnableMask(0xFFFFFFFF);
      // preserve color buffer, clear depth buffer
      mEdgeRenderer->setClearFlags(vl::CF_CLEAR_DEPTH);
      mEdgeRenderer->setEnableMask(0xFFFFFFFF);
      mEdgeRenderer->setShowCreases(false);
      mEdgeRenderer->setShowHiddenLines(false);
      vl::Log::print("Edge rendering enabled. Creases = off, hidden lines = off.\n");
    }
    else
    if (ch == '3')
    {
      mSolidRenderer->setEnableMask(0xFFFFFFFF);
      // preserve color buffer, clear depth buffer
      mEdgeRenderer->setClearFlags(vl::CF_CLEAR_DEPTH);
      mEdgeRenderer->setEnableMask(0xFFFFFFFF);
      mEdgeRenderer->setShowCreases(true);
      mEdgeRenderer->setShowHiddenLines(false);
      vl::Log::print("Edge rendering enabled. Creases = on, hidden lines = off.\n");
    }
    else
    if (ch == '4')
    {
      mSolidRenderer->setEnableMask(0xFFFFFFFF);
      // preserve color buffer, clear depth buffer
      mEdgeRenderer->setClearFlags(vl::CF_CLEAR_DEPTH);
      mEdgeRenderer->setEnableMask(0xFFFFFFFF);
      mEdgeRenderer->setShowCreases(true);
      mEdgeRenderer->setShowHiddenLines(true);
      vl::Log::print("Edge rendering enabled. Creases = on, hidden lines = on.\n");
    }
    else
    if (ch == '5')
    {
      mSolidRenderer->setEnableMask(0);
      // clear color and depth buffer
      mEdgeRenderer->setClearFlags(vl::CF_CLEAR_COLOR_DEPTH);
      mEdgeRenderer->setEnableMask(0xFFFFFFFF);
      mEdgeRenderer->setShowCreases(true);
      mEdgeRenderer->setShowHiddenLines(false);
      vl::Log::print("Hidden line removal wireframe enabled. Creases = on, hidden lines = off.\n");
    }
    if (ch == '6')
    {
      mSolidRenderer->setEnableMask(0);
      // clear color and depth buffer
      mEdgeRenderer->setClearFlags(vl::CF_CLEAR_COLOR_DEPTH);
      mEdgeRenderer->setEnableMask(0xFFFFFFFF);
      mEdgeRenderer->setShowCreases(true);
      mEdgeRenderer->setShowHiddenLines(true);
      vl::Log::print("Hidden line removal wireframe enabled. Creases = on, hidden lines = on.\n");
    }
  }

  void resizeEvent(int w, int h)
  {
    vl::Camera* camera = mRendering->camera();
    camera->viewport()->setWidth ( w );
    camera->viewport()->setHeight( h );
    camera->setProjectionAsPerspective();
  }

  void loadModel(const std::vector<vl::String>& files)
  {
    // resets the scene
    mSceneManager->tree()->actors()->clear();
    // resets the EdgeRenderer cache
    mEdgeRenderer->clearCache();

    for(unsigned int i=0; i<files.size(); ++i)
    {
      vl::ref<vl::ResourceDatabase> resource_db = vl::loadResource(files[i],true);

      if (!resource_db || resource_db->count<vl::Actor>() == 0)
      {
        vl::Log::error("No data found.\n");
        continue;
      }

      std::vector< vl::ref<vl::Actor> > actors;
      resource_db->get<vl::Actor>(actors);
      for(unsigned i=0; i<actors.size(); ++i)
      {
        vl::ref<vl::Actor> actor = actors[i].get();
        // define a reasonable Shader
        actor->effect()->shader()->setRenderState( new vl::Light(0) );
        actor->effect()->shader()->enable(vl::EN_DEPTH_TEST);
        actor->effect()->shader()->enable(vl::EN_LIGHTING);
        actor->effect()->shader()->gocLightModel()->setTwoSide(true);
        // add the actor to the scene
        mSceneManager->tree()->addActor( actor.get() );
      }
    }

    // position the camera to nicely see the objects in the scene
    trackball()->adjustView( mSceneManager.get(), vl::vec3(0,0,1)/*direction*/, vl::vec3(0,1,0)/*up*/, 1.0f/*bias*/ );
  }

  // laod the files dropped in the window
  void fileDroppedEvent(const std::vector<vl::String>& files) { loadModel(files); }

protected:
  vl::ref< vl::Renderer > mSolidRenderer;
  vl::ref< vl::EdgeRenderer > mEdgeRenderer;
  vl::ref<vl::Rendering> mRendering;
  vl::ref<vl::SceneManagerActorTree> mSceneManager;
};

// Have fun!
<|endoftext|>


<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

#include "libjoynrclustercontroller/mqtt/MosquittoConnection.h"

#include "joynr/ClusterControllerSettings.h"
#include "joynr/MessagingSettings.h"
#include "joynr/exceptions/JoynrException.h"

namespace joynr
{

INIT_LOGGER(MosquittoConnection);

MosquittoConnection::MosquittoConnection(const MessagingSettings& messagingSettings,
                                         const ClusterControllerSettings& ccSettings,
                                         const std::string& clientId)
        : mosquittopp(clientId.c_str(), false),
          messagingSettings(messagingSettings),
          host(messagingSettings.getBrokerUrl().getBrokerChannelsBaseUrl().getHost()),
          port(messagingSettings.getBrokerUrl().getBrokerChannelsBaseUrl().getPort()),
          channelId(),
          subscribeChannelMid(),
          topic(),
          additionalTopics(),
          additionalTopicsMutex(),
          isConnected(false),
          isRunning(false),
          isChannelIdRegistered(false),
          subscribedToChannelTopic(false),
          readyToSend(false),
          onMessageReceived(),
          onReadyToSendChangedMutex(),
          onReadyToSendChanged()
{
    mosqpp::lib_init();

    if (ccSettings.isMqttTlsEnabled()) {
        int rc = tls_set(ccSettings.getMqttCertificateAuthorityPemFilename().c_str(),
                         NULL,
                         ccSettings.getMqttCertificatePemFilename().c_str(),
                         ccSettings.getMqttPrivateKeyPemFilename().c_str());

        if (rc != MOSQ_ERR_SUCCESS) {
            JOYNR_LOG_ERROR(
                    logger, "Could not initialize TLS connection - {}", mosqpp::strerror(rc));
        }
    } else {
        JOYNR_LOG_DEBUG(logger, "MQTT connection not encrypted");
    }
}

MosquittoConnection::~MosquittoConnection()
{
    stop();
    stopLoop(true);

    mosqpp::lib_cleanup();
}

void MosquittoConnection::on_disconnect(int rc)
{
    setReadyToSend(false);
    isConnected = false;

    if (rc == 0) {
        JOYNR_LOG_DEBUG(logger, "Disconnected from tcp://{}:{}", host, port);
    } else {
        JOYNR_LOG_ERROR(logger,
                        "Unexpectedly disconnected from tcp://{}:{}, error: {}",
                        host,
                        port,
                        mosqpp::strerror(rc));
        reconnect();
        return;
    }
    stopLoop();
}

void MosquittoConnection::on_log(int level, const char* str)
{
    if (level == MOSQ_LOG_ERR) {
        JOYNR_LOG_ERROR(logger, "Mosquitto Log: {}", str);
    } else if (level == MOSQ_LOG_WARNING) {
        JOYNR_LOG_WARN(logger, "Mosquitto Log: {}", str);
    } else if (level == MOSQ_LOG_INFO) {
        JOYNR_LOG_INFO(logger, "Mosquitto Log: {}", str);
    } else {
        // MOSQ_LOG_NOTICE || MOSQ_LOG_DEBUG || any other log level
        JOYNR_LOG_DEBUG(logger, "Mosquitto Log: {}", str);
    }
}

std::uint16_t MosquittoConnection::getMqttQos() const
{
    return mqttQos;
}

std::string MosquittoConnection::getMqttPrio() const
{
    static const std::string value("low");
    return value;
}

bool MosquittoConnection::isMqttRetain() const
{
    return mqttRetain;
}

void MosquittoConnection::start()
{
    JOYNR_LOG_TRACE(
            logger, "Start called with isRunning: {}, isConnected: {}", isRunning, isConnected);

    JOYNR_LOG_DEBUG(logger, "Try to connect to tcp://{}:{}", host, port);
    connect_async(host.c_str(), port, messagingSettings.getMqttKeepAliveTimeSeconds().count());

    reconnect_delay_set(messagingSettings.getMqttReconnectDelayTimeSeconds().count(),
                        messagingSettings.getMqttReconnectDelayTimeSeconds().count(),
                        false);

    startLoop();
}

void MosquittoConnection::startLoop()
{
    int rc = loop_start();
    if (rc == MOSQ_ERR_SUCCESS) {
        JOYNR_LOG_TRACE(logger, "Mosquitto loop started");
        isRunning = true;
    } else {
        JOYNR_LOG_ERROR(logger,
                        "Mosquitto loop start failed: error: {} ({})",
                        std::to_string(rc),
                        mosqpp::strerror(rc));
    }
}

void MosquittoConnection::stop()
{
    if (isConnected) {
        int rc = disconnect();

        if (rc == MOSQ_ERR_SUCCESS) {
            JOYNR_LOG_TRACE(logger, "Mosquitto Connection disconnected");
        } else {
            JOYNR_LOG_ERROR(logger,
                            "Mosquitto disconnect failed: error: {} ({})",
                            std::to_string(rc),
                            mosqpp::strerror(rc));
            stopLoop(true);
            mosqpp::lib_cleanup();
        }
    } else if (isRunning) {
        stopLoop(true);
        mosqpp::lib_cleanup();
    }
    setReadyToSend(false);
}

void MosquittoConnection::stopLoop(bool force)
{
    int rc = loop_stop(force);

    if (rc == MOSQ_ERR_SUCCESS) {
        isRunning = false;
        JOYNR_LOG_TRACE(logger, "Mosquitto loop stopped");
    } else {
        JOYNR_LOG_ERROR(logger,
                        "Mosquitto loop stop failed: error: {} ({})",
                        std::to_string(rc),
                        mosqpp::strerror(rc));
    }
}

void MosquittoConnection::on_connect(int rc)
{
    if (rc > 0) {
        JOYNR_LOG_ERROR(logger,
                        "Mosquitto Connection Error: {} ({})",
                        std::to_string(rc),
                        mosqpp::strerror(rc));
    } else {
        JOYNR_LOG_DEBUG(logger, "Mosquitto Connection established");
        isConnected = true;

        createSubscriptions();
    }
}

void MosquittoConnection::createSubscriptions()
{
    while (!isChannelIdRegistered && isRunning) {
        std::this_thread::sleep_for(std::chrono::milliseconds(25));
    }
    try {
        subscribeToTopicInternal(topic, true);
        std::lock_guard<std::recursive_mutex> lock(additionalTopicsMutex);
        for (const std::string& additionalTopic : additionalTopics) {
            subscribeToTopicInternal(additionalTopic);
        }
    } catch (const exceptions::JoynrRuntimeException& error) {
        JOYNR_LOG_ERROR(logger, "Error subscribing to Mqtt topic, error: ", error.getMessage());
    }
}

void MosquittoConnection::subscribeToTopicInternal(const std::string& topic,
                                                   const bool isChannelTopic)
{
    int* mid = nullptr;
    if (isChannelTopic) {
        mid = &subscribeChannelMid;
    }
    int rc = subscribe(mid, topic.c_str(), getMqttQos());
    switch (rc) {
    case (MOSQ_ERR_SUCCESS):
        JOYNR_LOG_DEBUG(logger, "Subscribed to {}", topic);
        break;
    case (MOSQ_ERR_NO_CONN):
        JOYNR_LOG_DEBUG(logger,
                        "Subscription to {} failed: error: {} (not connected to a broker). "
                        "Subscription will be restored on connect.",
                        topic,
                        std::to_string(rc));
        break;
    default:
        // MOSQ_ERR_INVAL, MOSQ_ERR_NOMEM
        std::string errorMsg = "Subscription to " + topic + " failed: error: " +
                               std::to_string(rc) + " (" + mosqpp::strerror(rc) + ")";
        throw exceptions::JoynrRuntimeException(errorMsg);
    }
}

void MosquittoConnection::subscribeToTopic(const std::string& topic)
{
    while (!isChannelIdRegistered && isRunning) {
        std::this_thread::sleep_for(std::chrono::milliseconds(25));
    }
    {
        std::lock_guard<std::recursive_mutex> lock(additionalTopicsMutex);
        if (additionalTopics.find(topic) != additionalTopics.end()) {
            JOYNR_LOG_DEBUG(logger, "already subscribed to topic {}", topic);
            return;
        }
        subscribeToTopicInternal(topic);
        additionalTopics.insert(topic);
    }
}

void MosquittoConnection::unsubscribeFromTopic(const std::string& topic)
{
    if (isChannelIdRegistered) {
        std::lock_guard<std::recursive_mutex> lock(additionalTopicsMutex);
        if (additionalTopics.find(topic) == additionalTopics.end()) {
            JOYNR_LOG_DEBUG(logger, "Unsubscribe called for non existing topic {}", topic);
            return;
        }
        additionalTopics.erase(topic);
        if (isConnected && isRunning) {
            int rc = unsubscribe(nullptr, topic.c_str());
            if (rc == MOSQ_ERR_SUCCESS) {
                JOYNR_LOG_DEBUG(logger, "Unsubscribed from {}", topic);
            } else {
                // MOSQ_ERR_INVAL || MOSQ_ERR_NOMEM || MOSQ_ERR_NO_CONN
                JOYNR_LOG_ERROR(logger,
                                "Unsubscribe from {} failed: error: {} ({})",
                                topic,
                                std::to_string(rc),
                                mosqpp::strerror(rc));
            }
        }
    }
}

void MosquittoConnection::publishMessage(
        const std::string& topic,
        const int qosLevel,
        const std::function<void(const exceptions::JoynrRuntimeException&)>& onFailure,
        uint32_t payloadlen = 0,
        const void* payload = nullptr)
{
    JOYNR_LOG_DEBUG(logger, "Publish to {}", topic);

    int mid;
    int rc = publish(&mid, topic.c_str(), payloadlen, payload, qosLevel, isMqttRetain());
    if (!(rc == MOSQ_ERR_SUCCESS)) {
        if (rc == MOSQ_ERR_INVAL || rc == MOSQ_ERR_PAYLOAD_SIZE) {
            onFailure(exceptions::JoynrMessageNotSentException(
                    "message could not be sent: mid (mqtt message id): " + std::to_string(mid) +
                    ", error: " + std::to_string(rc) + " (" + mosqpp::strerror(rc) + ")"));
        }
        // MOSQ_ERR_NOMEM || MOSQ_ERR_NO_CONN || MOSQ_ERR_PROTOCOL ||| unexpected errors
        onFailure(exceptions::JoynrDelayMessageException(
                "error sending message: mid (mqtt message id): " + std::to_string(mid) +
                ", error: " + std::to_string(rc) + " (" + mosqpp::strerror(rc) + ")"));
    }
    JOYNR_LOG_TRACE(logger, "published message with mqtt message id {}", std::to_string(mid));
}

void MosquittoConnection::registerChannelId(const std::string& channelId)
{
    this->channelId = channelId;
    topic = channelId + "/" + getMqttPrio() + "/" + "#";
    isChannelIdRegistered = true;
}

void MosquittoConnection::registerReceiveCallback(
        std::function<void(smrf::ByteVector&&)> onMessageReceived)
{
    this->onMessageReceived = onMessageReceived;
}

void MosquittoConnection::registerReadyToSendChangedCallback(
        std::function<void(bool)> onReadyToSendChanged)
{
    std::lock_guard<std::mutex> lock(onReadyToSendChangedMutex);
    this->onReadyToSendChanged = std::move(onReadyToSendChanged);
}

bool MosquittoConnection::isSubscribedToChannelTopic() const
{
    return subscribedToChannelTopic;
}

bool MosquittoConnection::isReadyToSend() const
{
    return readyToSend;
}

void MosquittoConnection::on_subscribe(int mid, int qos_count, const int* granted_qos)
{
    JOYNR_LOG_DEBUG(logger, "Subscribed (mid: {} with granted QOS {}", mid, granted_qos[0]);

    for (int i = 1; i < qos_count; i++) {
        JOYNR_LOG_DEBUG(logger, "QOS: {} granted {}", i, granted_qos[i]);
    }

    if (mid == subscribeChannelMid) {
        subscribedToChannelTopic = true;
        setReadyToSend(isConnected);
    }
}

void MosquittoConnection::on_message(const mosquitto_message* message)
{
    if (!onMessageReceived) {
        JOYNR_LOG_ERROR(
                logger, "Discarding received message, since onMessageReceived callback is empty.");
        return;
    }

    std::uint8_t* data = static_cast<std::uint8_t*>(message->payload);
    smrf::ByteVector rawMessage(data, data + message->payloadlen);
    onMessageReceived(std::move(rawMessage));
}

void MosquittoConnection::on_publish(int mid)
{
    JOYNR_LOG_TRACE(logger, "published message with mid {}", std::to_string(mid));
}

void MosquittoConnection::setReadyToSend(bool readyToSend)
{
    if (this->readyToSend != readyToSend) {
        this->readyToSend = readyToSend;

        std::lock_guard<std::mutex> lock(onReadyToSendChangedMutex);
        if (onReadyToSendChanged) {
            onReadyToSendChanged(readyToSend);
        }
    }
}

} // namespace joynr
<commit_msg>[C++] Always log MQTT client ID when creating an MQTT connection.<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

#include "libjoynrclustercontroller/mqtt/MosquittoConnection.h"

#include "joynr/ClusterControllerSettings.h"
#include "joynr/MessagingSettings.h"
#include "joynr/exceptions/JoynrException.h"

namespace joynr
{

INIT_LOGGER(MosquittoConnection);

MosquittoConnection::MosquittoConnection(const MessagingSettings& messagingSettings,
                                         const ClusterControllerSettings& ccSettings,
                                         const std::string& clientId)
        : mosquittopp(clientId.c_str(), false),
          messagingSettings(messagingSettings),
          host(messagingSettings.getBrokerUrl().getBrokerChannelsBaseUrl().getHost()),
          port(messagingSettings.getBrokerUrl().getBrokerChannelsBaseUrl().getPort()),
          channelId(),
          subscribeChannelMid(),
          topic(),
          additionalTopics(),
          additionalTopicsMutex(),
          isConnected(false),
          isRunning(false),
          isChannelIdRegistered(false),
          subscribedToChannelTopic(false),
          readyToSend(false),
          onMessageReceived(),
          onReadyToSendChangedMutex(),
          onReadyToSendChanged()
{
    JOYNR_LOG_INFO(logger, "Init mosquitto connection using MQTT client ID: {}", clientId);
    mosqpp::lib_init();

    if (ccSettings.isMqttTlsEnabled()) {
        int rc = tls_set(ccSettings.getMqttCertificateAuthorityPemFilename().c_str(),
                         NULL,
                         ccSettings.getMqttCertificatePemFilename().c_str(),
                         ccSettings.getMqttPrivateKeyPemFilename().c_str());

        if (rc != MOSQ_ERR_SUCCESS) {
            JOYNR_LOG_ERROR(
                    logger, "Could not initialize TLS connection - {}", mosqpp::strerror(rc));
        }
    } else {
        JOYNR_LOG_DEBUG(logger, "MQTT connection not encrypted");
    }
}

MosquittoConnection::~MosquittoConnection()
{
    stop();
    stopLoop(true);

    mosqpp::lib_cleanup();
}

void MosquittoConnection::on_disconnect(int rc)
{
    setReadyToSend(false);
    isConnected = false;

    if (rc == 0) {
        JOYNR_LOG_DEBUG(logger, "Disconnected from tcp://{}:{}", host, port);
    } else {
        JOYNR_LOG_ERROR(logger,
                        "Unexpectedly disconnected from tcp://{}:{}, error: {}",
                        host,
                        port,
                        mosqpp::strerror(rc));
        reconnect();
        return;
    }
    stopLoop();
}

void MosquittoConnection::on_log(int level, const char* str)
{
    if (level == MOSQ_LOG_ERR) {
        JOYNR_LOG_ERROR(logger, "Mosquitto Log: {}", str);
    } else if (level == MOSQ_LOG_WARNING) {
        JOYNR_LOG_WARN(logger, "Mosquitto Log: {}", str);
    } else if (level == MOSQ_LOG_INFO) {
        JOYNR_LOG_INFO(logger, "Mosquitto Log: {}", str);
    } else {
        // MOSQ_LOG_NOTICE || MOSQ_LOG_DEBUG || any other log level
        JOYNR_LOG_DEBUG(logger, "Mosquitto Log: {}", str);
    }
}

std::uint16_t MosquittoConnection::getMqttQos() const
{
    return mqttQos;
}

std::string MosquittoConnection::getMqttPrio() const
{
    static const std::string value("low");
    return value;
}

bool MosquittoConnection::isMqttRetain() const
{
    return mqttRetain;
}

void MosquittoConnection::start()
{
    JOYNR_LOG_TRACE(
            logger, "Start called with isRunning: {}, isConnected: {}", isRunning, isConnected);

    JOYNR_LOG_DEBUG(logger, "Try to connect to tcp://{}:{}", host, port);
    connect_async(host.c_str(), port, messagingSettings.getMqttKeepAliveTimeSeconds().count());

    reconnect_delay_set(messagingSettings.getMqttReconnectDelayTimeSeconds().count(),
                        messagingSettings.getMqttReconnectDelayTimeSeconds().count(),
                        false);

    startLoop();
}

void MosquittoConnection::startLoop()
{
    int rc = loop_start();
    if (rc == MOSQ_ERR_SUCCESS) {
        JOYNR_LOG_TRACE(logger, "Mosquitto loop started");
        isRunning = true;
    } else {
        JOYNR_LOG_ERROR(logger,
                        "Mosquitto loop start failed: error: {} ({})",
                        std::to_string(rc),
                        mosqpp::strerror(rc));
    }
}

void MosquittoConnection::stop()
{
    if (isConnected) {
        int rc = disconnect();

        if (rc == MOSQ_ERR_SUCCESS) {
            JOYNR_LOG_TRACE(logger, "Mosquitto Connection disconnected");
        } else {
            JOYNR_LOG_ERROR(logger,
                            "Mosquitto disconnect failed: error: {} ({})",
                            std::to_string(rc),
                            mosqpp::strerror(rc));
            stopLoop(true);
            mosqpp::lib_cleanup();
        }
    } else if (isRunning) {
        stopLoop(true);
        mosqpp::lib_cleanup();
    }
    setReadyToSend(false);
}

void MosquittoConnection::stopLoop(bool force)
{
    int rc = loop_stop(force);

    if (rc == MOSQ_ERR_SUCCESS) {
        isRunning = false;
        JOYNR_LOG_TRACE(logger, "Mosquitto loop stopped");
    } else {
        JOYNR_LOG_ERROR(logger,
                        "Mosquitto loop stop failed: error: {} ({})",
                        std::to_string(rc),
                        mosqpp::strerror(rc));
    }
}

void MosquittoConnection::on_connect(int rc)
{
    if (rc > 0) {
        JOYNR_LOG_ERROR(logger,
                        "Mosquitto Connection Error: {} ({})",
                        std::to_string(rc),
                        mosqpp::strerror(rc));
    } else {
        JOYNR_LOG_DEBUG(logger, "Mosquitto Connection established");
        isConnected = true;

        createSubscriptions();
    }
}

void MosquittoConnection::createSubscriptions()
{
    while (!isChannelIdRegistered && isRunning) {
        std::this_thread::sleep_for(std::chrono::milliseconds(25));
    }
    try {
        subscribeToTopicInternal(topic, true);
        std::lock_guard<std::recursive_mutex> lock(additionalTopicsMutex);
        for (const std::string& additionalTopic : additionalTopics) {
            subscribeToTopicInternal(additionalTopic);
        }
    } catch (const exceptions::JoynrRuntimeException& error) {
        JOYNR_LOG_ERROR(logger, "Error subscribing to Mqtt topic, error: ", error.getMessage());
    }
}

void MosquittoConnection::subscribeToTopicInternal(const std::string& topic,
                                                   const bool isChannelTopic)
{
    int* mid = nullptr;
    if (isChannelTopic) {
        mid = &subscribeChannelMid;
    }
    int rc = subscribe(mid, topic.c_str(), getMqttQos());
    switch (rc) {
    case (MOSQ_ERR_SUCCESS):
        JOYNR_LOG_DEBUG(logger, "Subscribed to {}", topic);
        break;
    case (MOSQ_ERR_NO_CONN):
        JOYNR_LOG_DEBUG(logger,
                        "Subscription to {} failed: error: {} (not connected to a broker). "
                        "Subscription will be restored on connect.",
                        topic,
                        std::to_string(rc));
        break;
    default:
        // MOSQ_ERR_INVAL, MOSQ_ERR_NOMEM
        std::string errorMsg = "Subscription to " + topic + " failed: error: " +
                               std::to_string(rc) + " (" + mosqpp::strerror(rc) + ")";
        throw exceptions::JoynrRuntimeException(errorMsg);
    }
}

void MosquittoConnection::subscribeToTopic(const std::string& topic)
{
    while (!isChannelIdRegistered && isRunning) {
        std::this_thread::sleep_for(std::chrono::milliseconds(25));
    }
    {
        std::lock_guard<std::recursive_mutex> lock(additionalTopicsMutex);
        if (additionalTopics.find(topic) != additionalTopics.end()) {
            JOYNR_LOG_DEBUG(logger, "already subscribed to topic {}", topic);
            return;
        }
        subscribeToTopicInternal(topic);
        additionalTopics.insert(topic);
    }
}

void MosquittoConnection::unsubscribeFromTopic(const std::string& topic)
{
    if (isChannelIdRegistered) {
        std::lock_guard<std::recursive_mutex> lock(additionalTopicsMutex);
        if (additionalTopics.find(topic) == additionalTopics.end()) {
            JOYNR_LOG_DEBUG(logger, "Unsubscribe called for non existing topic {}", topic);
            return;
        }
        additionalTopics.erase(topic);
        if (isConnected && isRunning) {
            int rc = unsubscribe(nullptr, topic.c_str());
            if (rc == MOSQ_ERR_SUCCESS) {
                JOYNR_LOG_DEBUG(logger, "Unsubscribed from {}", topic);
            } else {
                // MOSQ_ERR_INVAL || MOSQ_ERR_NOMEM || MOSQ_ERR_NO_CONN
                JOYNR_LOG_ERROR(logger,
                                "Unsubscribe from {} failed: error: {} ({})",
                                topic,
                                std::to_string(rc),
                                mosqpp::strerror(rc));
            }
        }
    }
}

void MosquittoConnection::publishMessage(
        const std::string& topic,
        const int qosLevel,
        const std::function<void(const exceptions::JoynrRuntimeException&)>& onFailure,
        uint32_t payloadlen = 0,
        const void* payload = nullptr)
{
    JOYNR_LOG_DEBUG(logger, "Publish to {}", topic);

    int mid;
    int rc = publish(&mid, topic.c_str(), payloadlen, payload, qosLevel, isMqttRetain());
    if (!(rc == MOSQ_ERR_SUCCESS)) {
        if (rc == MOSQ_ERR_INVAL || rc == MOSQ_ERR_PAYLOAD_SIZE) {
            onFailure(exceptions::JoynrMessageNotSentException(
                    "message could not be sent: mid (mqtt message id): " + std::to_string(mid) +
                    ", error: " + std::to_string(rc) + " (" + mosqpp::strerror(rc) + ")"));
        }
        // MOSQ_ERR_NOMEM || MOSQ_ERR_NO_CONN || MOSQ_ERR_PROTOCOL ||| unexpected errors
        onFailure(exceptions::JoynrDelayMessageException(
                "error sending message: mid (mqtt message id): " + std::to_string(mid) +
                ", error: " + std::to_string(rc) + " (" + mosqpp::strerror(rc) + ")"));
    }
    JOYNR_LOG_TRACE(logger, "published message with mqtt message id {}", std::to_string(mid));
}

void MosquittoConnection::registerChannelId(const std::string& channelId)
{
    this->channelId = channelId;
    topic = channelId + "/" + getMqttPrio() + "/" + "#";
    isChannelIdRegistered = true;
}

void MosquittoConnection::registerReceiveCallback(
        std::function<void(smrf::ByteVector&&)> onMessageReceived)
{
    this->onMessageReceived = onMessageReceived;
}

void MosquittoConnection::registerReadyToSendChangedCallback(
        std::function<void(bool)> onReadyToSendChanged)
{
    std::lock_guard<std::mutex> lock(onReadyToSendChangedMutex);
    this->onReadyToSendChanged = std::move(onReadyToSendChanged);
}

bool MosquittoConnection::isSubscribedToChannelTopic() const
{
    return subscribedToChannelTopic;
}

bool MosquittoConnection::isReadyToSend() const
{
    return readyToSend;
}

void MosquittoConnection::on_subscribe(int mid, int qos_count, const int* granted_qos)
{
    JOYNR_LOG_DEBUG(logger, "Subscribed (mid: {} with granted QOS {}", mid, granted_qos[0]);

    for (int i = 1; i < qos_count; i++) {
        JOYNR_LOG_DEBUG(logger, "QOS: {} granted {}", i, granted_qos[i]);
    }

    if (mid == subscribeChannelMid) {
        subscribedToChannelTopic = true;
        setReadyToSend(isConnected);
    }
}

void MosquittoConnection::on_message(const mosquitto_message* message)
{
    if (!onMessageReceived) {
        JOYNR_LOG_ERROR(
                logger, "Discarding received message, since onMessageReceived callback is empty.");
        return;
    }

    std::uint8_t* data = static_cast<std::uint8_t*>(message->payload);
    smrf::ByteVector rawMessage(data, data + message->payloadlen);
    onMessageReceived(std::move(rawMessage));
}

void MosquittoConnection::on_publish(int mid)
{
    JOYNR_LOG_TRACE(logger, "published message with mid {}", std::to_string(mid));
}

void MosquittoConnection::setReadyToSend(bool readyToSend)
{
    if (this->readyToSend != readyToSend) {
        this->readyToSend = readyToSend;

        std::lock_guard<std::mutex> lock(onReadyToSendChangedMutex);
        if (onReadyToSendChanged) {
            onReadyToSendChanged(readyToSend);
        }
    }
}

} // namespace joynr
<|endoftext|>


<commit_before>/**
 * @file CommonAPIClient.hpp
 * @author Denis Kotov
 * @date 3 Apr 2017
 * @brief Contains CommonAPIClient wrapper class for creating client
 * @copyright MIT License. Open source: https://github.com/redradist/Inter-Component-Communication.git
 */

#ifndef ICC_COMMONAPI_CLIENT_COMPONENT_HPP
#define ICC_COMMONAPI_CLIENT_COMPONENT_HPP

#include <CommonAPI/CommonAPI.hpp>
#include <type_traits>
#include <logger/DummyLogger.hpp>

namespace icc {

namespace commonapi {

template< template< typename ... _AttributeExtensions > class Proxy,
          typename Logger = icc::logger::DummyLogger >
class CommonAPIClient
    : public Proxy<>
    , public virtual Logger {
  static_assert(std::is_base_of<CommonAPI::Proxy, Proxy<>>::value,
                "Proxy does not derived from CommonAPI::Proxy");
 public:
  CommonAPIClient(const std::string &_domain,
                  const std::string &_instance) :
      Proxy<>([=]() {
        Logger::debug("Building CommonAPIClient ...");
        std::shared_ptr<CommonAPI::Runtime> runtime = CommonAPI::Runtime::get();
        auto proxy = runtime->buildProxy<Proxy>(_domain, _instance);
        if (!proxy) {
          Logger::error("proxy is nullptr");
        } else {
          Logger::debug("CommonAPIClient is built successfully !!");
          proxy->getProxyStatusEvent().subscribe(
          [=](const CommonAPI::AvailabilityStatus & _status) mutable {
            if (CommonAPI::AvailabilityStatus::AVAILABLE == _status) {
              Logger::debug("CommonAPIClient is connected");
              connected(*this);
            } else {
              Logger::debug("CommonAPIClient is disconnected");
              disconnected(*this);
            }
          });
        }
        return proxy;
      }()) {
    Logger::debug("Constructor CommonAPIClient");
  }

  CommonAPIClient(CommonAPIClient const &) = default;
  CommonAPIClient & operator=(CommonAPIClient const &) = default;
  CommonAPIClient(CommonAPIClient &&) = default;
  CommonAPIClient & operator=(CommonAPIClient &&) = default;

  virtual ~CommonAPIClient() = default;

  virtual void connected(Proxy<> &) = 0;
  virtual void disconnected(Proxy<> &) = 0;
};

}

}

#endif // ICC_COMMONAPI_CLIENT_COMPONENT_HPP
<commit_msg>Fixed warnings in CommonAPIClients<commit_after>/**
 * @file CommonAPIClient.hpp
 * @author Denis Kotov
 * @date 3 Apr 2017
 * @brief Contains CommonAPIClient wrapper class for creating client
 * @copyright MIT License. Open source: https://github.com/redradist/Inter-Component-Communication.git
 */

#ifndef ICC_COMMONAPI_CLIENT_COMPONENT_HPP
#define ICC_COMMONAPI_CLIENT_COMPONENT_HPP

#include <CommonAPI/CommonAPI.hpp>
#include <type_traits>
#include <logger/DummyLogger.hpp>

namespace icc {

namespace commonapi {

template< template< typename ... _AttributeExtensions > class Proxy,
          typename Logger = icc::logger::DummyLogger >
class CommonAPIClient
    : public Proxy<>
    , public virtual Logger {
  static_assert(std::is_base_of<CommonAPI::Proxy, Proxy<>>::value,
                "Proxy does not derived from CommonAPI::Proxy");
 public:
  CommonAPIClient(const std::string &_domain,
                  const std::string &_instance) :
      Proxy<>([=]() {
        Logger::debug("Building CommonAPIClient ...");
        std::shared_ptr<CommonAPI::Runtime> runtime = CommonAPI::Runtime::get();
        auto proxy = runtime->buildProxy<Proxy>(_domain, _instance);
        if (!proxy) {
          Logger::error("proxy is nullptr");
        } else {
          Logger::debug("CommonAPIClient is built successfully !!");
          proxy->getProxyStatusEvent().subscribe(
          [=](const CommonAPI::AvailabilityStatus & _status) mutable {
            if (CommonAPI::AvailabilityStatus::AVAILABLE == _status) {
              Logger::debug("CommonAPIClient is connected");
              connected(*this);
            } else {
              Logger::debug("CommonAPIClient is disconnected");
              disconnected(*this);
            }
          });
        }
        return proxy;
      }()) {
    Logger::debug("Constructor CommonAPIClient");
  }

  CommonAPIClient(CommonAPIClient const &) = default;
  CommonAPIClient & operator=(CommonAPIClient const &) = default;
  CommonAPIClient(CommonAPIClient &&) = delete;
  CommonAPIClient & operator=(CommonAPIClient &&) = delete;

  virtual ~CommonAPIClient() = default;

  virtual void connected(Proxy<> &) = 0;
  virtual void disconnected(Proxy<> &) = 0;
};

}

}

#endif // ICC_COMMONAPI_CLIENT_COMPONENT_HPP
<|endoftext|>


<commit_before>#ifndef DICE_GETNUMBEROPERATION_H
#define DICE_GETNUMBEROPERATION_H

#include "IOperation.hpp"

class GetNumberOperation : public IOperation
{
    const int _number;		// stores number given by a constructor

    // It's called directly by evaluate, so check its doc.
    std::unique_ptr<RollResult> execute();

public:
    explicit GetNumberOperation(int);

    std::unique_ptr<RollResult> evaluate();
};

#endif //DICE_GETNUMBEROPERATION_H
<commit_msg>Added documentation for GetNumberOperation class.<commit_after>#ifndef DICE_GETNUMBEROPERATION_H
#define DICE_GETNUMBEROPERATION_H

#include "IOperation.hpp"

/**
 * \brief Creates RollResult from singular value.
 */
class GetNumberOperation : public IOperation
{
    const int _number;		// stores number given by a constructor

    // It's called directly by evaluate, so check its doc.
    std::unique_ptr<RollResult> execute();

public:
    /**
     * \brief Operation that creates singular value RollResult.
     *
     * It's a primitive operation that should be a base for decorators.
     *
     * \param number Integer value that we want to pass to other
     * operations.
     */
    explicit GetNumberOperation(int number);

    /**
     * \brief Evaluates an operation.
     *
     * \return Returns unique pointer to RollResult containing singular
     * value specified while calling constructor.
     */
    std::unique_ptr<RollResult> evaluate();
};

#endif //DICE_GETNUMBEROPERATION_H
<|endoftext|>


<commit_before>#include "ledpoi.h"
#include "ledpoi_utils.h"

#include "memory/memoryTask.h"
#include "dispatch/dispatchTask.h"
#include "display/displayTask.h"
#include "player/playerTask.h"
#include "program/programTask.h"
#include "wifi/wifiTask.h"
#include "uart/uartTask.h"
#include "ui/button.h"
#include "selftest/selftestTask.h"

// unless defined differently below this is the default log level
#define DEFAULT_LOG_LEVEL ESP_LOG_INFO

void logging_setup(){

    esp_log_level_set(DSPCH_T, ESP_LOG_DEBUG);       // dispatch task
    esp_log_level_set(DISP_T,  DEFAULT_LOG_LEVEL);   // display task
    esp_log_level_set(WIFI_T,  ESP_LOG_DEBUG);       // wifi task
    esp_log_level_set(UART_T,  ESP_LOG_DEBUG);       // uart task
    esp_log_level_set(PROG_T,  ESP_LOG_DEBUG);       // program task
    esp_log_level_set(PLAY_T,  ESP_LOG_DEBUG);       // play task
    esp_log_level_set(MEM_T,   DEFAULT_LOG_LEVEL);   // memory task
    esp_log_level_set(SELF_T,  DEFAULT_LOG_LEVEL);   // selftest task
    esp_log_level_set(BUT_T,   DEFAULT_LOG_LEVEL);   // button task
    esp_log_level_set(EXPL_T,  DEFAULT_LOG_LEVEL);   // example task

    esp_log_level_set(PLAYF_A, DEFAULT_LOG_LEVEL);   // play frames action
    esp_log_level_set(NOACT_A, DEFAULT_LOG_LEVEL);   // void ("no") action
    esp_log_level_set(ANIM_A,  DEFAULT_LOG_LEVEL);   // animation action

    esp_log_level_set(TIMER,   DEFAULT_LOG_LEVEL);   // timer util
    esp_log_level_set(POICMD,  DEFAULT_LOG_LEVEL);   // poi command util
    esp_log_level_set(ICACHE,  DEFAULT_LOG_LEVEL);   // image cache util
    esp_log_level_set(PCACHE,  DEFAULT_LOG_LEVEL);   // program cache util
    esp_log_level_set(RWIFIS,  ESP_LOG_DEBUG);   // Robust wifi server
    esp_log_level_set(WIFI_U,  ESP_LOG_DEBUG);   // Robust wifi server utils
    esp_log_level_set(FLASH,   DEFAULT_LOG_LEVEL);   // flash memory
    esp_log_level_set(PROGH,   DEFAULT_LOG_LEVEL);   // program handler
    esp_log_level_set(INTS,    DEFAULT_LOG_LEVEL);   // interaction state
    esp_log_level_set(SELF_H,  DEFAULT_LOG_LEVEL);   // selftest helper
}

void setup() {
  uart_setup(); // first one because this sets serial baudrate
  logging_setup();

  // setup tasks and queues with sizes
  button_setup();
  memory_setup(10);
  dispatch_setup(10);
  display_setup(5);
  player_setup(5);
  program_setup(3);
  wifi_setup(3);

  // start tasks with prios
  button_start(8);
  memory_start(8);
  dispatch_start(7);
  program_start(6, 5);
  player_start(4);
  display_start(3);
  wifi_start(8);
  uart_start(5);

  // send wifi start command to central dispatch queue after everything is set up
  PoiCommand cmdStartWifi ({CONNECT, 0, 0, 0, 0, 0});
  sendToDispatch(cmdStartWifi, WIFI_T);

	// start selftest
  // selftest_start(5);

  // fill queues with example values
  PoiCommand cmdWorm ( {ANIMATE, RAINBOW, 1, 5, 0, 100} );
  sendToDispatch(cmdWorm, WIFI_T);
  PoiCommand cmdBlack ( {SHOW_RGB, 0, 0, 0, 0, 0} ); // black
  sendToDispatch(cmdBlack, WIFI_T);
}

// everything works with tasks, we dont need the loop...
void loop(){
  delay(100000); // snow white sleep
}<commit_msg>back to default log level<commit_after>#include "ledpoi.h"
#include "ledpoi_utils.h"

#include "memory/memoryTask.h"
#include "dispatch/dispatchTask.h"
#include "display/displayTask.h"
#include "player/playerTask.h"
#include "program/programTask.h"
#include "wifi/wifiTask.h"
#include "uart/uartTask.h"
#include "ui/button.h"
#include "selftest/selftestTask.h"

// unless defined differently below this is the default log level
#define DEFAULT_LOG_LEVEL ESP_LOG_INFO

void logging_setup(){

    esp_log_level_set(DSPCH_T, ESP_LOG_DEBUG);       // dispatch task
    esp_log_level_set(DISP_T,  DEFAULT_LOG_LEVEL);   // display task
    esp_log_level_set(WIFI_T,  ESP_LOG_DEBUG);       // wifi task
    esp_log_level_set(UART_T,  ESP_LOG_DEBUG);       // uart task
    esp_log_level_set(PROG_T,  ESP_LOG_DEBUG);       // program task
    esp_log_level_set(PLAY_T,  ESP_LOG_DEBUG);       // play task
    esp_log_level_set(MEM_T,   DEFAULT_LOG_LEVEL);   // memory task
    esp_log_level_set(SELF_T,  DEFAULT_LOG_LEVEL);   // selftest task
    esp_log_level_set(BUT_T,   DEFAULT_LOG_LEVEL);   // button task
    esp_log_level_set(EXPL_T,  DEFAULT_LOG_LEVEL);   // example task

    esp_log_level_set(PLAYF_A, DEFAULT_LOG_LEVEL);   // play frames action
    esp_log_level_set(NOACT_A, DEFAULT_LOG_LEVEL);   // void ("no") action
    esp_log_level_set(ANIM_A,  DEFAULT_LOG_LEVEL);   // animation action

    esp_log_level_set(TIMER,   DEFAULT_LOG_LEVEL);   // timer util
    esp_log_level_set(POICMD,  DEFAULT_LOG_LEVEL);   // poi command util
    esp_log_level_set(ICACHE,  DEFAULT_LOG_LEVEL);   // image cache util
    esp_log_level_set(PCACHE,  DEFAULT_LOG_LEVEL);   // program cache util
    esp_log_level_set(RWIFIS,  DEFAULT_LOG_LEVEL);   // Robust wifi server
    esp_log_level_set(WIFI_U,  DEFAULT_LOG_LEVEL);   // Robust wifi server utils
    esp_log_level_set(FLASH,   DEFAULT_LOG_LEVEL);   // flash memory
    esp_log_level_set(PROGH,   DEFAULT_LOG_LEVEL);   // program handler
    esp_log_level_set(INTS,    DEFAULT_LOG_LEVEL);   // interaction state
    esp_log_level_set(SELF_H,  DEFAULT_LOG_LEVEL);   // selftest helper
}

void setup() {
  uart_setup(); // first one because this sets serial baudrate
  logging_setup();

  // setup tasks and queues with sizes
  button_setup();
  memory_setup(10);
  dispatch_setup(10);
  display_setup(5);
  player_setup(5);
  program_setup(3);
  wifi_setup(3);

  // start tasks with prios
  button_start(8);
  memory_start(8);
  dispatch_start(7);
  program_start(6, 5);
  player_start(4);
  display_start(3);
  wifi_start(8);
  uart_start(5);

  // send wifi start command to central dispatch queue after everything is set up
  PoiCommand cmdStartWifi ({CONNECT, 0, 0, 0, 0, 0});
  sendToDispatch(cmdStartWifi, WIFI_T);

	// start selftest
  // selftest_start(5);

  // fill queues with example values
  PoiCommand cmdWorm ( {ANIMATE, RAINBOW, 1, 5, 0, 100} );
  sendToDispatch(cmdWorm, WIFI_T);
  PoiCommand cmdBlack ( {SHOW_RGB, 0, 0, 0, 0, 0} ); // black
  sendToDispatch(cmdBlack, WIFI_T);
}

// everything works with tasks, we dont need the loop...
void loop(){
  delay(100000); // snow white sleep
}<|endoftext|>