<commit_before>// -------------------------------------------------------------------------
//    @FileName         :    NFCDataList.h
//    @Author           :    LvSheng.Huang
//    @Date             :    2012-03-01
//    @Module           :    NFCDataList
//
// -------------------------------------------------------------------------

#include <cstdarg>
#include "NFCDataList.h"
#include "NFIDataList.h"

NFCDataList::NFCDataList()
: NFIDataList()
{
}

NFCDataList::NFCDataList(const char* str, const char* strSplit)
{
    Clear();

    Split(str, strSplit);
}

NFCDataList::NFCDataList(const NFCDataList& src)
{
    Clear();

    InnerAppendEx(src, 0, src.GetCount());
}

NFCDataList::NFCDataList(const NFIDataList& src)
{
    Clear();

    InnerAppendEx(src, 0, src.GetCount());
}

NFCDataList::~NFCDataList()
{
    Clear();
};

/*
NFCDataList& NFCDataList::operator=(const NFCDataList& src)
{
    Clear();
    InnerAppendEx(src, 0, src.GetCount());

    return *this;
}

NFCDataList& NFCDataList::operator=(const NFIDataList& src)
{
    Clear();
    InnerAppendEx(src, 0, src.GetCount());

    return *this;
}

*/
//
bool NFCDataList::Append(const NFIDataList& src, const int start, const int count)
{
    if (start >= src.GetCount())
    {
        return false;
    }

    int end = start + count;

    if (end > src.GetCount())
    {
        return false;
    }

    InnerAppendEx(src, start, end);

    return true;
}

bool NFCDataList::Append(const NFIDataList::TData& TData)
{
    if (TData.nType <= TDATA_UNKNOWN
        || TData.nType >= TDATA_MAX)
    {
        return false;
    }

	switch (TData.nType)
	{
	case TDATA_INT:
	case TDATA_FLOAT:
	case TDATA_DOUBLE:
	case TDATA_OBJECT:
		{
			AddValue(TData.nType, TData.variantData);
		}
		break;
	case TDATA_STRING:
		{
			const std::string& strData = boost::get<std::string>(TData.variantData);
			AddString(strData);
		}
		break;
	default:
		break;
	}

    return false;
}

bool NFCDataList::Append( const NFIDataList& src )
{
	return Append(src, 0, src.GetCount());
}

bool NFCDataList::Add(const NFINT64 value)
{
    return NFIDataList::AddValue<NFINT64>(TDATA_INT, value);
}

bool NFCDataList::Add(const float value)
{
    return AddValue<float>(TDATA_FLOAT, value);
}

bool NFCDataList::Add(const double value)
{
    return AddValue<double>(TDATA_DOUBLE, value);
}

bool NFCDataList::Add(const char* value)
{
    return AddValue<std::string>(TDATA_STRING, std::string(value));
}

bool NFCDataList::Add(const std::string& value)
{
    return AddValue<std::string>(TDATA_STRING, value);
}

bool NFCDataList::Add(const NFIDENTID& value)
{
    return AddValue<NFIDENTID>(TDATA_OBJECT, value);
}

bool NFCDataList::Add(const void* value)
{
    //return AddNumber<const void*>(TDATA_POINTER, value);
    return true;
}

bool NFCDataList::Set(const int index, const NFINT64 value)
{
    if (index < GetCount() && index >= 0)
    {
        return SetValue(index, value);
    }

    return false;
}
bool NFCDataList::Set(const int index, const float value)
{
    if (index < GetCount() && index >= 0)
    {
        return SetValue(index, value);
    }

    return false;
}
bool NFCDataList::Set(const int index, const double value)
{
    if (index < GetCount() && index >= 0)
    {
        return SetValue(index, value);
    }

    return false;
}
bool NFCDataList::Set(const int index, const char* value)
{
    if (index < GetCount() && index > 0)
    {
		return SetString(index, value);
    }

    return false;
}

bool NFCDataList::Set(const int index, const NFIDENTID& value)
{
    if (index < GetCount() && index >= 0)
    {
        return SetValue<NFIDENTID>(index, value);
    }

    return false;
}

bool NFCDataList::Set(const int index, const void* value)
{
    if (index < GetCount() && index >= 0)
    {
        //return SetNumber(index, value);
    }

    return false;
}

NFINT64 NFCDataList::Int(const int index) const
{
    if (index < GetCount() && index >= 0)
    {
        return NumberVal<NFINT64>(index);
    }

    return 0;
}

float NFCDataList::Float(const int index) const
{
    if (index < GetCount() && index >= 0)
    {
        return NumberVal<float>(index);
    }

    return 0.0f;
}

double NFCDataList::Double(const int index) const
{
    if (index < GetCount() && index >= 0)
    {
        return NumberVal<double>(index);
    }

    return 0.0f;
}

const std::string& NFCDataList::String(const int index) const
{
    if (index < GetCount() && index >= 0)
    {
        const NF_SHARE_PTR<TData> var = mvList[index];
        if (var && TDATA_STRING == var->nType)
        {
            return boost::get<const std::string&>(var->variantData);
        }
    }

    return NULL_STR;
}

NFIDENTID NFCDataList::Object(const int index) const
{
//    if (index < GetCount() && index >= 0)
//    {
//        return NumberVal<NFIDENTID>(index);
//    }

    if (index < GetCount() && index >= 0)
    {
        NFIDENTID result;
        if (index < GetCount() && index >= 0)
        {
            TDATA_TYPE type = Type(index);
            if (type == TDATA_OBJECT)
            {
                NF_SHARE_PTR<TData> var = GetStack(index);
                result = boost::get<NFIDENTID>(var->variantData);
            }
        }

        return result;
    }

    return NFIDENTID();
}

void* NFCDataList::Pointer(const int index) const
{
    if (index < GetCount() && index >= 0)
    {
        return NumberVal<void*>(index);
    }

    return NULL;
}

bool NFCDataList::Split(const char* str, const char* strSplit)
{
	Clear();

    std::string strData(str);
    if (strData.empty())
    {
        return true;
    }

    std::string temstrSplit(strSplit);
    std::string::size_type pos;
    strData += temstrSplit;
    std::string::size_type size = strData.length();

    for (std::string::size_type i = 0; i < size; i++)
    {
        pos = int(strData.find(temstrSplit, i));
        if (pos < size)
        {
            std::string strSub = strData.substr(i, pos - i);
            Add(strSub.c_str());

            i = pos + temstrSplit.size() - 1;
        }
    }

    return true;
}

TDATA_TYPE NFCDataList::Type(const int index) const
{
    if (index >= GetCount() || index < 0)
    {
        return TDATA_UNKNOWN;
    }

    if (index < STACK_SIZE)
    {
        return mvList[index]->nType;
    }
    else
    {
        const NF_SHARE_PTR<TData> pData = GetStack(index);
        if (pData)
        {
            return pData->nType;
        }
    }

    return TDATA_UNKNOWN;
}

bool NFCDataList::TypeEx(const int nType, ...) const
{
    bool bRet = true;

    if (TDATA_UNKNOWN == nType)
    {
        bRet = false;
        return bRet;
    }

    TDATA_TYPE pareType = (TDATA_TYPE)nType;
    va_list arg_ptr;
    va_start(arg_ptr, nType);
    int index = 0;

    while (pareType != TDATA_UNKNOWN)
    {
        //Ƚ
        TDATA_TYPE varType = Type(index);
        if (varType != pareType)
        {
            bRet = false;
            break;
        }

        ++index;
        pareType = (TDATA_TYPE)va_arg(arg_ptr, int);   //ȡһ
    }

    va_end(arg_ptr); //

    return bRet;
}

bool NFCDataList::Concat(const NFIDataList& src)
{
    InnerAppendEx(src, 0, src.GetCount());
    return true;
}

void NFCDataList::Clear()
{
	mnUseSize = 0;
    //mnCapacity = STACK_SIZE;
	//8Ժ
	if (mvList.size() > STACK_SIZE)
	{
		for (int i = 0; i < STACK_SIZE; ++i)
		{
			mvList[i]->nType = TDATA_UNKNOWN;
		}

		mvList.erase(mvList.begin() + 8, mvList.end());
	}
}

bool NFCDataList::IsEmpty() const
{
    return (0 == mnUseSize);
}

int NFCDataList::GetCount() const
{
    return mnUseSize;
}

void NFCDataList::InnerAppendEx(const NFIDataList& src, const int start, const int end)
{
    for (int i = start; i < end; ++i)
    {
        TDATA_TYPE vType = src.Type(i);
        switch (vType)
        {
            case TDATA_INT:
                AddValue<NFINT64>(vType, src.Int(i));
                break;
            case TDATA_FLOAT:
                AddValue<float>(vType, src.Float(i));
                break;
            case TDATA_DOUBLE:
                AddValue<double>(vType, src.Double(i));
                break;
            case TDATA_STRING:
                AddString(src.String(i).c_str());
                break;
            case TDATA_OBJECT:
                AddValue<NFIDENTID>(vType, src.Object(i));
                break;
                //case TDATA_POINTER:
                //    AddNumber<void*>(vType, src.NumberVal<void*>(i));
                //    break;
            default:
                //Assert(0);
                break;
        }
    }
}

std::string NFCDataList::StringValEx(const int index, const bool bForce) const
{
    if (index < GetCount() && index >= 0)
    {
        TDATA_TYPE type =  Type(index);
        if (type == TDATA_STRING)
        {
            return String(index);
        }

//         const NF_SHARE_PTR<NFIDataList::TData> var = GetStack(index);
//         if (var)
//         {
//             //return boost::lexical_cast<std::string>(var->variantData);
//         }
    }

    return NULL_STR;
}

bool NFCDataList::ToString(std::string& str, const char* strSplit) const
{
    for (int i = 0; i < GetCount(); ++i)
    {
        std::string strVal = StringValEx(i, true);
        str += strVal;
        str += strSplit;
    }

    std::string strTempSplit(strSplit);
    std::string::size_type nPos = str.rfind(strSplit);
    if (nPos == str.length() - strTempSplit.length())
    {
        str = str.substr(0, nPos);
    }

    return true;
}
<commit_msg>fixed bug for set data<commit_after>// -------------------------------------------------------------------------
//    @FileName         :    NFCDataList.h
//    @Author           :    LvSheng.Huang
//    @Date             :    2012-03-01
//    @Module           :    NFCDataList
//
// -------------------------------------------------------------------------

#include <cstdarg>
#include "NFCDataList.h"
#include "NFIDataList.h"

NFCDataList::NFCDataList()
: NFIDataList()
{
}

NFCDataList::NFCDataList(const char* str, const char* strSplit)
{
    Clear();

    Split(str, strSplit);
}

NFCDataList::NFCDataList(const NFCDataList& src)
{
    Clear();

    InnerAppendEx(src, 0, src.GetCount());
}

NFCDataList::NFCDataList(const NFIDataList& src)
{
    Clear();

    InnerAppendEx(src, 0, src.GetCount());
}

NFCDataList::~NFCDataList()
{
    Clear();
};

/*
NFCDataList& NFCDataList::operator=(const NFCDataList& src)
{
    Clear();
    InnerAppendEx(src, 0, src.GetCount());

    return *this;
}

NFCDataList& NFCDataList::operator=(const NFIDataList& src)
{
    Clear();
    InnerAppendEx(src, 0, src.GetCount());

    return *this;
}

*/
//
bool NFCDataList::Append(const NFIDataList& src, const int start, const int count)
{
    if (start >= src.GetCount())
    {
        return false;
    }

    int end = start + count;

    if (end > src.GetCount())
    {
        return false;
    }

    InnerAppendEx(src, start, end);

    return true;
}

bool NFCDataList::Append(const NFIDataList::TData& TData)
{
    if (TData.nType <= TDATA_UNKNOWN
        || TData.nType >= TDATA_MAX)
    {
        return false;
    }

	switch (TData.nType)
	{
	case TDATA_INT:
	case TDATA_FLOAT:
	case TDATA_DOUBLE:
	case TDATA_OBJECT:
		{
			AddValue(TData.nType, TData.variantData);
		}
		break;
	case TDATA_STRING:
		{
			const std::string& strData = boost::get<std::string>(TData.variantData);
			AddString(strData);
		}
		break;
	default:
		break;
	}

    return false;
}

bool NFCDataList::Append( const NFIDataList& src )
{
	return Append(src, 0, src.GetCount());
}

bool NFCDataList::Add(const NFINT64 value)
{
    return NFIDataList::AddValue<NFINT64>(TDATA_INT, value);
}

bool NFCDataList::Add(const float value)
{
    return AddValue<float>(TDATA_FLOAT, value);
}

bool NFCDataList::Add(const double value)
{
    return AddValue<double>(TDATA_DOUBLE, value);
}

bool NFCDataList::Add(const char* value)
{
    return AddValue<std::string>(TDATA_STRING, std::string(value));
}

bool NFCDataList::Add(const std::string& value)
{
    return AddValue<std::string>(TDATA_STRING, value);
}

bool NFCDataList::Add(const NFIDENTID& value)
{
    return AddValue<NFIDENTID>(TDATA_OBJECT, value);
}

bool NFCDataList::Add(const void* value)
{
    //return AddNumber<const void*>(TDATA_POINTER, value);
    return true;
}

bool NFCDataList::Set(const int index, const NFINT64 value)
{
    if (index < GetCount() && index >= 0)
    {
        return SetValue(index, value);
    }

    return false;
}
bool NFCDataList::Set(const int index, const float value)
{
    if (index < GetCount() && index >= 0)
    {
        return SetValue(index, value);
    }

    return false;
}
bool NFCDataList::Set(const int index, const double value)
{
    if (index < GetCount() && index >= 0)
    {
        return SetValue(index, value);
    }

    return false;
}
bool NFCDataList::Set(const int index, const char* value)
{
    if (index < GetCount() && index >= 0)
    {
		return SetString(index, value);
    }

    return false;
}

bool NFCDataList::Set(const int index, const NFIDENTID& value)
{
    if (index < GetCount() && index >= 0)
    {
        return SetValue<NFIDENTID>(index, value);
    }

    return false;
}

bool NFCDataList::Set(const int index, const void* value)
{
    if (index < GetCount() && index >= 0)
    {
        //return SetNumber(index, value);
    }

    return false;
}

NFINT64 NFCDataList::Int(const int index) const
{
    if (index < GetCount() && index >= 0)
    {
        return NumberVal<NFINT64>(index);
    }

    return 0;
}

float NFCDataList::Float(const int index) const
{
    if (index < GetCount() && index >= 0)
    {
        return NumberVal<float>(index);
    }

    return 0.0f;
}

double NFCDataList::Double(const int index) const
{
    if (index < GetCount() && index >= 0)
    {
        return NumberVal<double>(index);
    }

    return 0.0f;
}

const std::string& NFCDataList::String(const int index) const
{
    if (index < GetCount() && index >= 0)
    {
        const NF_SHARE_PTR<TData> var = mvList[index];
        if (var && TDATA_STRING == var->nType)
        {
            return boost::get<const std::string&>(var->variantData);
        }
    }

    return NULL_STR;
}

NFIDENTID NFCDataList::Object(const int index) const
{
//    if (index < GetCount() && index >= 0)
//    {
//        return NumberVal<NFIDENTID>(index);
//    }

    if (index < GetCount() && index >= 0)
    {
        NFIDENTID result;
        if (index < GetCount() && index >= 0)
        {
            TDATA_TYPE type = Type(index);
            if (type == TDATA_OBJECT)
            {
                NF_SHARE_PTR<TData> var = GetStack(index);
                result = boost::get<NFIDENTID>(var->variantData);
            }
        }

        return result;
    }

    return NFIDENTID();
}

void* NFCDataList::Pointer(const int index) const
{
    if (index < GetCount() && index >= 0)
    {
        return NumberVal<void*>(index);
    }

    return NULL;
}

bool NFCDataList::Split(const char* str, const char* strSplit)
{
	Clear();

    std::string strData(str);
    if (strData.empty())
    {
        return true;
    }

    std::string temstrSplit(strSplit);
    std::string::size_type pos;
    strData += temstrSplit;
    std::string::size_type size = strData.length();

    for (std::string::size_type i = 0; i < size; i++)
    {
        pos = int(strData.find(temstrSplit, i));
        if (pos < size)
        {
            std::string strSub = strData.substr(i, pos - i);
            Add(strSub.c_str());

            i = pos + temstrSplit.size() - 1;
        }
    }

    return true;
}

TDATA_TYPE NFCDataList::Type(const int index) const
{
    if (index >= GetCount() || index < 0)
    {
        return TDATA_UNKNOWN;
    }

    if (index < STACK_SIZE)
    {
        return mvList[index]->nType;
    }
    else
    {
        const NF_SHARE_PTR<TData> pData = GetStack(index);
        if (pData)
        {
            return pData->nType;
        }
    }

    return TDATA_UNKNOWN;
}

bool NFCDataList::TypeEx(const int nType, ...) const
{
    bool bRet = true;

    if (TDATA_UNKNOWN == nType)
    {
        bRet = false;
        return bRet;
    }

    TDATA_TYPE pareType = (TDATA_TYPE)nType;
    va_list arg_ptr;
    va_start(arg_ptr, nType);
    int index = 0;

    while (pareType != TDATA_UNKNOWN)
    {
        //Ƚ
        TDATA_TYPE varType = Type(index);
        if (varType != pareType)
        {
            bRet = false;
            break;
        }

        ++index;
        pareType = (TDATA_TYPE)va_arg(arg_ptr, int);   //ȡһ
    }

    va_end(arg_ptr); //

    return bRet;
}

bool NFCDataList::Concat(const NFIDataList& src)
{
    InnerAppendEx(src, 0, src.GetCount());
    return true;
}

void NFCDataList::Clear()
{
	mnUseSize = 0;
    //mnCapacity = STACK_SIZE;
	//8Ժ
	if (mvList.size() > STACK_SIZE)
	{
		for (int i = 0; i < STACK_SIZE; ++i)
		{
			mvList[i]->nType = TDATA_UNKNOWN;
		}

		mvList.erase(mvList.begin() + 8, mvList.end());
	}
}

bool NFCDataList::IsEmpty() const
{
    return (0 == mnUseSize);
}

int NFCDataList::GetCount() const
{
    return mnUseSize;
}

void NFCDataList::InnerAppendEx(const NFIDataList& src, const int start, const int end)
{
    for (int i = start; i < end; ++i)
    {
        TDATA_TYPE vType = src.Type(i);
        switch (vType)
        {
            case TDATA_INT:
                AddValue<NFINT64>(vType, src.Int(i));
                break;
            case TDATA_FLOAT:
                AddValue<float>(vType, src.Float(i));
                break;
            case TDATA_DOUBLE:
                AddValue<double>(vType, src.Double(i));
                break;
            case TDATA_STRING:
                AddString(src.String(i).c_str());
                break;
            case TDATA_OBJECT:
                AddValue<NFIDENTID>(vType, src.Object(i));
                break;
                //case TDATA_POINTER:
                //    AddNumber<void*>(vType, src.NumberVal<void*>(i));
                //    break;
            default:
                //Assert(0);
                break;
        }
    }
}

std::string NFCDataList::StringValEx(const int index, const bool bForce) const
{
    if (index < GetCount() && index >= 0)
    {
        TDATA_TYPE type =  Type(index);
        if (type == TDATA_STRING)
        {
            return String(index);
        }

//         const NF_SHARE_PTR<NFIDataList::TData> var = GetStack(index);
//         if (var)
//         {
//             //return boost::lexical_cast<std::string>(var->variantData);
//         }
    }

    return NULL_STR;
}

bool NFCDataList::ToString(std::string& str, const char* strSplit) const
{
    for (int i = 0; i < GetCount(); ++i)
    {
        std::string strVal = StringValEx(i, true);
        str += strVal;
        str += strSplit;
    }

    std::string strTempSplit(strSplit);
    std::string::size_type nPos = str.rfind(strSplit);
    if (nPos == str.length() - strTempSplit.length())
    {
        str = str.substr(0, nPos);
    }

    return true;
}
<|endoftext|>


<commit_before>// Common libraries
#include "version.h"
#include <stdio.h>
// PJON library
#define TS_RESPONSE_TIME_OUT 35000
#define PJON_INCLUDE_TS true // Include only ThroughSerial
#ifndef RPI
  #define RPI true
#endif
#include "PJON/PJON.h"
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
// RPI serial interface
#include <wiringPi.h>
#include <wiringSerial.h>
// gRPC library
#include <iostream>
#include <memory>
#include <grpc++/grpc++.h>
#include "pjongrpc.grpc.pb.h"

using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using pjongrpc::Arduino_Request;
using pjongrpc::Arduino_Reply;
using pjongrpc::Arduino;

// TODO: Find the way to change in from command line
PJON<ThroughSerial> bus(1);

uint64_t rcvd_cnt = 0;
std::string response;

static void receiver_function(
        uint8_t *payload,
        uint16_t length,
        const PJON_Packet_Info &packet_info){

  for (uint32_t i = 0; i != length; i++){
    response += payload[i];
  }

  rcvd_cnt += 1;
  std::cout << "#RCV snd_id=" << std::to_string(packet_info.sender_id)
            << " snd_net=";
                          for (uint32_t i = 0; i < sizeof(packet_info.sender_bus_id); i++) {
                            std::cout << std::to_string(packet_info.sender_bus_id[i]);
                            if (i < sizeof(packet_info.sender_bus_id) - 1)
                              std::cout << ".";
                          }
  std::cout << " rcv_id=" << std::to_string(packet_info.receiver_id)
            << " rcv_net=";
                          for (uint32_t i = 0; i < sizeof(packet_info.receiver_bus_id); i++) {
                            std::cout << std::to_string(packet_info.receiver_bus_id[i]);
                            if (i < sizeof(packet_info.receiver_bus_id) - 1)
                              std::cout << ".";
                          }
  std::cout << " id=" << std::to_string(packet_info.id)
            << " hdr=" << std::to_string(packet_info.header)
            << " pckt_cnt=" << std::to_string(rcvd_cnt)
            << " len=" << length
            << " data=" << response;
  std::cout << std::endl;
};

static void error_handler_function(uint8_t code, uint8_t data) {
  std::cout << "#ERR code=" << std::to_string(code);
  std::cout << " data=" << std::to_string(data);
  std::cout << std::endl;
};

bool is_enough_args(int argc, char **argv) {
  if (argc < 4)
    return false;
  return true;
}

bool is_first_arg_com_port(int argc, char **argv) {
  if (std::string(argv[1]).find("tty") != std::string::npos)
    return true;
  return false;
}

bool is_second_arg_bitrate(int argc, char **argv) {
  if (0 < std::stoi(std::string(argv[2])))
    if(std::stoi(std::string(argv[2]))  <= 153600)
      return true;
  return false;
}

bool is_third_arg_bus_id(int argc, char **argv) {
  if (0 <= std::stoi(std::string(argv[3])))
    if (std::stoi(std::string(argv[3])) <= 255)
      return true;
  return false;
}

void print_usage_help() {
  std::cout
      << "PJON_gRPC - gRPC server-client for PJON bus\n"
      << "VERSION: " << PJON_gRPC_SERVER_VERSION << "\n"
      << "\n"
      << "usage: pjon_grpc_server <COM PORT> <BITRATE> <NODE ID>\n"
      << "                           \\          \\         \\\n"
      << "                            \\          \\       0-255\n"
      << "                     /dev/ttyXXXX     1200 - 153600\n"
      << std::endl
      << "example: pjon_grpc_server /dev/ttyUSB0 57600 1" << std::endl
      << std::endl
      << "other options:" << std::endl
      << "   help - print this help" << std::endl
      << "version - displays program version" << std::endl
      << "--------------------------------------" << std::endl
      ;
}

void pjon_communication(int node_id, const char* data) {
  printf("Attempting to send a packet... \n");
  bus.send(node_id, data, strlen(data));
  printf("Attempting to roll bus... \n");
  bus.update();
  printf("Attempting to receive from bus... \n");
  bus.receive(5000000);
}

class ArduinoServiceImpl final : public Arduino::Service {
  Status RPiArduino(ServerContext* context, const Arduino_Request* request,
                  Arduino_Reply* reply) override {
    response = "";
    int node_id = request->node_id();
    const char* data = request->data().c_str();
    pjon_communication(node_id, data);
    reply->set_message(response);
    return Status::OK;
  }
};

void run_server() {
  std::string server_address("0.0.0.0:50051");
  ArduinoServiceImpl service;
  ServerBuilder builder;
  builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
  builder.RegisterService(&service);
  std::unique_ptr<Server> server(builder.BuildAndStart());
  std::cout << "Server listening on " << server_address << std::endl;
  server->Wait();
}

int main(int argc, char** argv) {
  if (argc == 2) {
    if (std::string(argv[1]) == "help") {
      print_usage_help();
      return 0;
    } else if (std::string(argv[1]) == "version") {
      std::cout << "VERSION: " << PJON_gRPC_SERVER_VERSION << "\n";
      return 0;
    }
    print_usage_help();
    std::cerr << "ERROR: option not supported\n";
    return 1;
  }
  if (!is_enough_args(argc, argv)) {
    print_usage_help();
    std::cerr << "ERROR: not enough args\n";
    return 1;
  }
  if (!is_first_arg_com_port(argc, argv)) {
    print_usage_help();
    std::cerr << "ERROR: first arg <COM PORT> should be /dev/ttyXXXX\n";
    return 1;
  }
  if (!is_second_arg_bitrate(argc, argv)) {
    print_usage_help();
    std::cerr << "ERROR: second arg <BITRATE> should specify bitrate 1 - 153600 like 2400, 19200, 38400, 57600, 115200, 153600\n";
    return 1;
  }
  if (!is_third_arg_bus_id(argc, argv)) {
    print_usage_help();
    std::cerr << "ERROR: third arg <NODE ID> should specify bus address 0 - 255\n";
    return 1;
  }

  char* com_str = argv[1];
  int bitRate = std::stoi(std::string(argv[2]));
// TODO: How we can define it globally?
//  PJON<ThroughSerial> bus(std::stoi(std::string(argv[3])));

  try {
    printf("Opening serial... \n");
    int s = serialOpen(com_str, bitRate);
    if (int(s) < 0) {
      printf("Serial open fail!\n");
      exit (EXIT_FAILURE);
    }
    if (wiringPiSetup() == -1) {
      printf("WiringPi setup fail");
      exit (EXIT_FAILURE);
    }

    printf("Setting serial... \n");
    bus.strategy.set_serial(s);
    bus.strategy.set_baud_rate(bitRate);

    printf("Opening bus... \n");
    bus.begin();
    bus.set_receiver(receiver_function);
    bus.set_error(error_handler_function);
    bus.set_synchronous_acknowledge(true);
    // crc_8 doesn't work correctly with 8.x PJON version, can be fixed in v9.x
    bus.set_crc_32(true);

    run_server();
    return 0;
  }
  catch (const char* msg) {
    std::cout << "exc: "
              << msg
              << std::endl;
    return 1;
  }
}
<commit_msg>some changes<commit_after>// Common libraries
#include "version.h"
#include <stdio.h>
// PJON library
#define TS_RESPONSE_TIME_OUT 75000
#define PJON_INCLUDE_TS true // Include only ThroughSerial
#ifndef RPI
  #define RPI true
#endif
#include "PJON/PJON.h"
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
// RPI serial interface
#include <wiringPi.h>
#include <wiringSerial.h>
// gRPC library
#include <iostream>
#include <memory>
#include <grpc++/grpc++.h>
#include "pjongrpc.grpc.pb.h"

using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using pjongrpc::Arduino_Request;
using pjongrpc::Arduino_Reply;
using pjongrpc::Arduino;

// TODO: Find the way to change in from command line
PJON<ThroughSerial> bus(1);

uint64_t rcvd_cnt = 0;
std::string response;

static void receiver_function(
        uint8_t *payload,
        uint16_t length,
        const PJON_Packet_Info &packet_info){

  for (uint32_t i = 0; i != length; i++){
    response += payload[i];
  }

  rcvd_cnt += 1;
  std::cout << "#RCV snd_id=" << std::to_string(packet_info.sender_id)
            << " snd_net=";
                          for (uint32_t i = 0; i < sizeof(packet_info.sender_bus_id); i++) {
                            std::cout << std::to_string(packet_info.sender_bus_id[i]);
                            if (i < sizeof(packet_info.sender_bus_id) - 1)
                              std::cout << ".";
                          }
  std::cout << " rcv_id=" << std::to_string(packet_info.receiver_id)
            << " rcv_net=";
                          for (uint32_t i = 0; i < sizeof(packet_info.receiver_bus_id); i++) {
                            std::cout << std::to_string(packet_info.receiver_bus_id[i]);
                            if (i < sizeof(packet_info.receiver_bus_id) - 1)
                              std::cout << ".";
                          }
  std::cout << " id=" << std::to_string(packet_info.id)
            << " hdr=" << std::to_string(packet_info.header)
            << " pckt_cnt=" << std::to_string(rcvd_cnt)
            << " len=" << length
            << " data=" << response;
  std::cout << std::endl;
};

static void error_handler_function(uint8_t code, uint8_t data) {
  std::cout << "#ERR code=" << std::to_string(code);
  std::cout << " data=" << std::to_string(data);
  std::cout << std::endl;
};

bool is_enough_args(int argc, char **argv) {
  if (argc < 4)
    return false;
  return true;
}

bool is_first_arg_com_port(int argc, char **argv) {
  if (std::string(argv[1]).find("tty") != std::string::npos)
    return true;
  return false;
}

bool is_second_arg_bitrate(int argc, char **argv) {
  if (0 < std::stoi(std::string(argv[2])))
    if(std::stoi(std::string(argv[2]))  <= 153600)
      return true;
  return false;
}

bool is_third_arg_bus_id(int argc, char **argv) {
  if (0 <= std::stoi(std::string(argv[3])))
    if (std::stoi(std::string(argv[3])) <= 255)
      return true;
  return false;
}

void print_usage_help() {
  std::cout
      << "PJON_gRPC - gRPC server-client for PJON bus\n"
      << "VERSION: " << PJON_gRPC_SERVER_VERSION << "\n"
      << "\n"
      << "usage: pjon_grpc_server <COM PORT> <BITRATE> <NODE ID>\n"
      << "                           \\          \\         \\\n"
      << "                            \\          \\       0-255\n"
      << "                     /dev/ttyXXXX     1200 - 153600\n"
      << std::endl
      << "example: pjon_grpc_server /dev/ttyUSB0 57600 1" << std::endl
      << std::endl
      << "other options:" << std::endl
      << "   help - print this help" << std::endl
      << "version - displays program version" << std::endl
      << "--------------------------------------" << std::endl
      ;
}

void pjon_communication(int node_id, const char* data) {
  printf(data);
  printf("\n");
  printf("Attempting to send a packet... \n");
  bus.send(node_id, data, strlen(data));
  printf("Attempting to roll bus... \n");
  bus.update();
  printf("Attempting to receive from bus... \n");
  bus.receive(5000000);
//uint32_t time = micros();
//while(micros() - time < 5000000) { bus.update(); bus.receive(); }
}

class ArduinoServiceImpl final : public Arduino::Service {
  Status RPiArduino(ServerContext* context, const Arduino_Request* request,
                  Arduino_Reply* reply) override {
    response = "";
    int node_id = request->node_id();
    const char* data = request->data().c_str();
    pjon_communication(node_id, data);
    reply->set_message(response);
    return Status::OK;
  }
};

void run_server() {
  std::string server_address("0.0.0.0:50051");
  ArduinoServiceImpl service;
  ServerBuilder builder;
  builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
  builder.RegisterService(&service);
  std::unique_ptr<Server> server(builder.BuildAndStart());
  std::cout << "Server listening on " << server_address << std::endl;
  server->Wait();
}

int main(int argc, char** argv) {
  if (argc == 2) {
    if (std::string(argv[1]) == "help") {
      print_usage_help();
      return 0;
    } else if (std::string(argv[1]) == "version") {
      std::cout << "VERSION: " << PJON_gRPC_SERVER_VERSION << "\n";
      return 0;
    }
    print_usage_help();
    std::cerr << "ERROR: option not supported\n";
    return 1;
  }
  if (!is_enough_args(argc, argv)) {
    print_usage_help();
    std::cerr << "ERROR: not enough args\n";
    return 1;
  }
  if (!is_first_arg_com_port(argc, argv)) {
    print_usage_help();
    std::cerr << "ERROR: first arg <COM PORT> should be /dev/ttyXXXX\n";
    return 1;
  }
  if (!is_second_arg_bitrate(argc, argv)) {
    print_usage_help();
    std::cerr << "ERROR: second arg <BITRATE> should specify bitrate 1 - 153600 like 2400, 19200, 38400, 57600, 115200, 153600\n";
    return 1;
  }
  if (!is_third_arg_bus_id(argc, argv)) {
    print_usage_help();
    std::cerr << "ERROR: third arg <NODE ID> should specify bus address 0 - 255\n";
    return 1;
  }

  char* com_str = argv[1];
  int bitRate = std::stoi(std::string(argv[2]));
// TODO: How we can define it globally?
//  PJON<ThroughSerial> bus(std::stoi(std::string(argv[3])));

  try {
    printf("Opening serial... \n");
    int s = serialOpen(com_str, bitRate);
    if (int(s) < 0) {
      printf("Serial open fail!\n");
      exit (EXIT_FAILURE);
    }
    if (wiringPiSetup() == -1) {
      printf("WiringPi setup fail");
      exit (EXIT_FAILURE);
    }

    printf("Setting serial... \n");
    bus.strategy.set_serial(s);
    bus.strategy.set_baud_rate(bitRate);

    printf("Opening bus... \n");
    bus.begin();
    bus.set_receiver(receiver_function);
    bus.set_error(error_handler_function);
    bus.set_synchronous_acknowledge(true);
    // crc_8 doesn't work correctly with 8.x PJON version, can be fixed in v9.x
    bus.set_crc_32(true);

    run_server();
    return 0;
  }
  catch (const char* msg) {
    std::cout << "exc: "
              << msg
              << std::endl;
    return 1;
  }

}
<|endoftext|>


<commit_before>#ifndef STRONG_TYPEDEF_HPP
#define STRONG_TYPEDEF_HPP

#include <type_traits>
#include <functional>

namespace osrm
{

/* Creates strongly typed wrappers around scalar types.
 * Useful for stopping accidental assignment of lats to lons,
 * etc.  Also clarifies what this random "int" value is
 * being used for.
 */
#define OSRM_STRONG_TYPEDEF(From, To)                                                              \
    class To final                                                                                \
    {                                                                                \
        static_assert(std::is_arithmetic<From>(), "");                                             \
        From x;                                                                                \
                                                                                \
      public:                                                                                \
        To() = default;                                                                            \
        explicit To(const From x_) : x(x_) {}                                                      \
        explicit operator From &() { return x; }                                                   \
        explicit operator const From &() const { return x; }                                       \
        bool operator<(const To &z_) const { return x < static_cast<const From>(z_); }             \
        bool operator>(const To &z_) const { return x > static_cast<const From>(z_); }             \
        bool operator<=(const To &z_) const { return x <= static_cast<const From>(z_); }           \
        bool operator>=(const To &z_) const { return x >= static_cast<const From>(z_); }           \
        bool operator==(const To &z_) const { return x == static_cast<const From>(z_); }           \
        bool operator!=(const To &z_) const { return x != static_cast<const From>(z_); }           \
    };                                                                                \
    inline From To##_to_##From(To to) { return static_cast<From>(to); }                            \
    namespace std                                                                                \
    {                                                                                \
    template <> struct hash<To>                                                                    \
    {                                                                                \
        std::size_t operator()(const To &k) const                                                  \
        {                                                                                \
            return std::hash<From>()(static_cast<const From>(k));                                  \
        }                                                                                \
    };                                                                                \
    }
}

#endif // OSRM_STRONG_TYPEDEF_HPP
<commit_msg>Add operator<< to OSRM_STRONG_TYPEDEF<commit_after>#ifndef STRONG_TYPEDEF_HPP
#define STRONG_TYPEDEF_HPP

#include <iostream>
#include <type_traits>
#include <functional>

namespace osrm
{

/* Creates strongly typed wrappers around scalar types.
 * Useful for stopping accidental assignment of lats to lons,
 * etc.  Also clarifies what this random "int" value is
 * being used for.
 */
#define OSRM_STRONG_TYPEDEF(From, To)                                                              \
    class To final                                                                                \
    {                                                                                \
        static_assert(std::is_arithmetic<From>(), "");                                             \
        From x;                                                                                \
        friend std::ostream& operator<<(std::ostream& stream, const To& inst);                     \
                                                                                \
      public:                                                                                \
        To() = default;                                                                            \
        explicit To(const From x_) : x(x_) {}                                                      \
        explicit operator From &() { return x; }                                                   \
        explicit operator const From &() const { return x; }                                       \
        bool operator<(const To &z_) const { return x < static_cast<const From>(z_); }             \
        bool operator>(const To &z_) const { return x > static_cast<const From>(z_); }             \
        bool operator<=(const To &z_) const { return x <= static_cast<const From>(z_); }           \
        bool operator>=(const To &z_) const { return x >= static_cast<const From>(z_); }           \
        bool operator==(const To &z_) const { return x == static_cast<const From>(z_); }           \
        bool operator!=(const To &z_) const { return x != static_cast<const From>(z_); }           \
    };                                                                                \
    inline From To##_to_##From(To to) { return static_cast<From>(to); }                            \
    namespace std                                                                                \
    {                                                                                \
    template <> struct hash<To>                                                                    \
    {                                                                                \
        std::size_t operator()(const To &k) const                                                  \
        {                                                                                \
            return std::hash<From>()(static_cast<const From>(k));                                  \
        }                                                                                \
    };                                                                                \
    }                                                                                \
    inline std::ostream& operator<<(std::ostream& stream, const To& inst) {                        \
        return stream << #To << '(' << inst.x << ')';                                              \
    }
}

#endif // OSRM_STRONG_TYPEDEF_HPP
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/notifications/desktop_notification_service.h"

#include "base/memory/ref_counted.h"
#include "base/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/browser/notifications/notifications_prefs_cache.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/testing_profile.h"
#include "content/browser/browser_thread.h"
#include "content/browser/renderer_host/test_render_view_host.h"
#include "grit/generated_resources.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNotificationPresenter.h"

namespace {

// NotificationsPrefsCache wants to be called on the IO thread. This class
// routes calls to the cache on the IO thread.
class ThreadProxy : public base::RefCountedThreadSafe<ThreadProxy> {
 public:
  ThreadProxy()
      : io_event_(false, false),
        ui_event_(false, false),
        permission_(0) {
    // The current message loop was already initalized by the test superclass.
    ui_thread_.reset(
        new BrowserThread(BrowserThread::UI, MessageLoop::current()));

    // Create IO thread, start its message loop.
    io_thread_.reset(new BrowserThread(BrowserThread::IO));
    io_thread_->Start();

    // Calling PauseIOThread() here isn't safe, because the runnable method
    // could complete before the constructor is done, deleting |this|.
  }

  int CacheHasPermission(NotificationsPrefsCache* cache, const GURL& url) {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
        NewRunnableMethod(this, &ThreadProxy::CacheHasPermissionIO,
                          make_scoped_refptr(cache), url));
    io_event_.Signal();
    ui_event_.Wait();  // Wait for IO thread to be done.
    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
        NewRunnableMethod(this, &ThreadProxy::PauseIOThreadIO));

    return permission_;
  }

  void PauseIOThread() {
    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
        NewRunnableMethod(this, &ThreadProxy::PauseIOThreadIO));
  }

  void DrainIOThread() {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    io_event_.Signal();
    io_thread_->Stop();
  }

 private:
  friend class base::RefCountedThreadSafe<ThreadProxy>;
  ~ThreadProxy() {
     DrainIOThread();
  }

  void PauseIOThreadIO() {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
    io_event_.Wait();
  }

  void CacheHasPermissionIO(NotificationsPrefsCache* cache, const GURL& url) {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
    permission_ = cache->HasPermission(url);
    ui_event_.Signal();
  }

  base::WaitableEvent io_event_;
  base::WaitableEvent ui_event_;
  scoped_ptr<BrowserThread> ui_thread_;
  scoped_ptr<BrowserThread> io_thread_;

  int permission_;
};

class DesktopNotificationServiceTest : public RenderViewHostTestHarness {
 public:
  DesktopNotificationServiceTest() {
  }

  virtual void SetUp() {
    RenderViewHostTestHarness::SetUp();
    proxy_ = new ThreadProxy;
    proxy_->PauseIOThread();

    // Creates the service, calls InitPrefs() on it which loads data from the
    // profile into the cache and then puts the cache in io thread mode.
    service_ = profile()->GetDesktopNotificationService();
    cache_ = service_->prefs_cache();
  }

  virtual void TearDown() {
    // The io thread's waiting on the io_event_ might hold a ref to |proxy_|,
    // preventing its destruction. Clear that ref.
    proxy_->DrainIOThread();
    RenderViewHostTestHarness::TearDown();
  }

  DesktopNotificationService* service_;
  NotificationsPrefsCache* cache_;
  scoped_refptr<ThreadProxy> proxy_;
};

TEST_F(DesktopNotificationServiceTest, DefaultContentSettingSentToCache) {
  // The default pref registered in DesktopNotificationService is "ask",
  // and that's what sent to the cache.
  EXPECT_EQ(CONTENT_SETTING_ASK, cache_->CachedDefaultContentSetting());

  // Change the default content setting. This will post a task on the IO thread
  // to update the cache.
  service_->SetDefaultContentSetting(CONTENT_SETTING_BLOCK);

  // The updated pref shouldn't be sent to the cache immediately.
  EXPECT_EQ(CONTENT_SETTING_ASK, cache_->CachedDefaultContentSetting());

  // Run IO thread tasks.
  proxy_->DrainIOThread();

  // Now that IO thread events have been processed, it should be there.
  EXPECT_EQ(CONTENT_SETTING_BLOCK, cache_->CachedDefaultContentSetting());
}

TEST_F(DesktopNotificationServiceTest, SettingsForSchemes) {
  GURL url("file:///html/test.html");

  EXPECT_EQ(CONTENT_SETTING_ASK, cache_->CachedDefaultContentSetting());
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, url));

  service_->GrantPermission(url);
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionAllowed,
            proxy_->CacheHasPermission(cache_, url));

  service_->DenyPermission(url);
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionDenied,
            proxy_->CacheHasPermission(cache_, url));

  GURL https_url("https://testurl");
  GURL http_url("http://testurl");
  EXPECT_EQ(CONTENT_SETTING_ASK, cache_->CachedDefaultContentSetting());
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, http_url));
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, https_url));

  service_->GrantPermission(https_url);
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionAllowed,
            proxy_->CacheHasPermission(cache_, https_url));
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, http_url));

  service_->DenyPermission(http_url);
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionDenied,
            proxy_->CacheHasPermission(cache_, http_url));
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionAllowed,
            proxy_->CacheHasPermission(cache_, https_url));
}

TEST_F(DesktopNotificationServiceTest, GrantPermissionSentToCache) {
  GURL url("http://allowed.com");
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, url));

  service_->GrantPermission(url);

  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionAllowed,
            proxy_->CacheHasPermission(cache_, url));
}

TEST_F(DesktopNotificationServiceTest, DenyPermissionSentToCache) {
  GURL url("http://denied.com");
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, url));

  service_->DenyPermission(url);

  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionDenied,
            proxy_->CacheHasPermission(cache_, url));
}

TEST_F(DesktopNotificationServiceTest, PrefChangesSentToCache) {
  PrefService* prefs = profile()->GetPrefs();

  ListValue* allowed_sites =
      prefs->GetMutableList(prefs::kDesktopNotificationAllowedOrigins);
  {
    allowed_sites->Append(new StringValue(GURL("http://allowed.com").spec()));
    ScopedUserPrefUpdate updateAllowed(
        prefs, prefs::kDesktopNotificationAllowedOrigins);
  }

  ListValue* denied_sites =
      prefs->GetMutableList(prefs::kDesktopNotificationDeniedOrigins);
  {
    denied_sites->Append(new StringValue(GURL("http://denied.com").spec()));
    ScopedUserPrefUpdate updateDenied(
        prefs, prefs::kDesktopNotificationDeniedOrigins);
  }

  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionAllowed,
            proxy_->CacheHasPermission(cache_, GURL("http://allowed.com")));
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionDenied,
            proxy_->CacheHasPermission(cache_, GURL("http://denied.com")));
}

TEST_F(DesktopNotificationServiceTest, GetAllowedOrigins) {
  service_->GrantPermission(GURL("http://allowed2.com"));
  service_->GrantPermission(GURL("http://allowed.com"));

  std::vector<GURL> allowed_origins(service_->GetAllowedOrigins());
  ASSERT_EQ(2u, allowed_origins.size());
  EXPECT_EQ(GURL("http://allowed2.com"), allowed_origins[0]);
  EXPECT_EQ(GURL("http://allowed.com"), allowed_origins[1]);
}

TEST_F(DesktopNotificationServiceTest, GetBlockedOrigins) {
  service_->DenyPermission(GURL("http://denied2.com"));
  service_->DenyPermission(GURL("http://denied.com"));

  std::vector<GURL> denied_origins(service_->GetBlockedOrigins());
  ASSERT_EQ(2u, denied_origins.size());
  EXPECT_EQ(GURL("http://denied2.com"), denied_origins[0]);
  EXPECT_EQ(GURL("http://denied.com"), denied_origins[1]);
}

TEST_F(DesktopNotificationServiceTest, ResetAllSentToCache) {
  GURL allowed_url("http://allowed.com");
  service_->GrantPermission(allowed_url);
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionAllowed,
            proxy_->CacheHasPermission(cache_, allowed_url));
  GURL denied_url("http://denied.com");
  service_->DenyPermission(denied_url);
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionDenied,
            proxy_->CacheHasPermission(cache_, denied_url));

  service_->ResetAllOrigins();

  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, allowed_url));
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, denied_url));
}

TEST_F(DesktopNotificationServiceTest, ResetAllowedSentToCache) {
  GURL allowed_url("http://allowed.com");
  service_->GrantPermission(allowed_url);
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionAllowed,
            proxy_->CacheHasPermission(cache_, allowed_url));

  service_->ResetAllowedOrigin(allowed_url);

  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, allowed_url));
}

TEST_F(DesktopNotificationServiceTest, ResetBlockedSentToCache) {
  GURL denied_url("http://denied.com");
  service_->DenyPermission(denied_url);
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionDenied,
            proxy_->CacheHasPermission(cache_, denied_url));

  service_->ResetBlockedOrigin(denied_url);

  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, denied_url));
}

}  // namespace
<commit_msg>Get rid of PrefService::GetMutableDictionary/GetMutableList<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/notifications/desktop_notification_service.h"

#include "base/memory/ref_counted.h"
#include "base/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/browser/notifications/notifications_prefs_cache.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/testing_profile.h"
#include "content/browser/browser_thread.h"
#include "content/browser/renderer_host/test_render_view_host.h"
#include "grit/generated_resources.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNotificationPresenter.h"

namespace {

// NotificationsPrefsCache wants to be called on the IO thread. This class
// routes calls to the cache on the IO thread.
class ThreadProxy : public base::RefCountedThreadSafe<ThreadProxy> {
 public:
  ThreadProxy()
      : io_event_(false, false),
        ui_event_(false, false),
        permission_(0) {
    // The current message loop was already initalized by the test superclass.
    ui_thread_.reset(
        new BrowserThread(BrowserThread::UI, MessageLoop::current()));

    // Create IO thread, start its message loop.
    io_thread_.reset(new BrowserThread(BrowserThread::IO));
    io_thread_->Start();

    // Calling PauseIOThread() here isn't safe, because the runnable method
    // could complete before the constructor is done, deleting |this|.
  }

  int CacheHasPermission(NotificationsPrefsCache* cache, const GURL& url) {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
        NewRunnableMethod(this, &ThreadProxy::CacheHasPermissionIO,
                          make_scoped_refptr(cache), url));
    io_event_.Signal();
    ui_event_.Wait();  // Wait for IO thread to be done.
    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
        NewRunnableMethod(this, &ThreadProxy::PauseIOThreadIO));

    return permission_;
  }

  void PauseIOThread() {
    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
        NewRunnableMethod(this, &ThreadProxy::PauseIOThreadIO));
  }

  void DrainIOThread() {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    io_event_.Signal();
    io_thread_->Stop();
  }

 private:
  friend class base::RefCountedThreadSafe<ThreadProxy>;
  ~ThreadProxy() {
     DrainIOThread();
  }

  void PauseIOThreadIO() {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
    io_event_.Wait();
  }

  void CacheHasPermissionIO(NotificationsPrefsCache* cache, const GURL& url) {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
    permission_ = cache->HasPermission(url);
    ui_event_.Signal();
  }

  base::WaitableEvent io_event_;
  base::WaitableEvent ui_event_;
  scoped_ptr<BrowserThread> ui_thread_;
  scoped_ptr<BrowserThread> io_thread_;

  int permission_;
};

class DesktopNotificationServiceTest : public RenderViewHostTestHarness {
 public:
  DesktopNotificationServiceTest() {
  }

  virtual void SetUp() {
    RenderViewHostTestHarness::SetUp();
    proxy_ = new ThreadProxy;
    proxy_->PauseIOThread();

    // Creates the service, calls InitPrefs() on it which loads data from the
    // profile into the cache and then puts the cache in io thread mode.
    service_ = profile()->GetDesktopNotificationService();
    cache_ = service_->prefs_cache();
  }

  virtual void TearDown() {
    // The io thread's waiting on the io_event_ might hold a ref to |proxy_|,
    // preventing its destruction. Clear that ref.
    proxy_->DrainIOThread();
    RenderViewHostTestHarness::TearDown();
  }

  DesktopNotificationService* service_;
  NotificationsPrefsCache* cache_;
  scoped_refptr<ThreadProxy> proxy_;
};

TEST_F(DesktopNotificationServiceTest, DefaultContentSettingSentToCache) {
  // The default pref registered in DesktopNotificationService is "ask",
  // and that's what sent to the cache.
  EXPECT_EQ(CONTENT_SETTING_ASK, cache_->CachedDefaultContentSetting());

  // Change the default content setting. This will post a task on the IO thread
  // to update the cache.
  service_->SetDefaultContentSetting(CONTENT_SETTING_BLOCK);

  // The updated pref shouldn't be sent to the cache immediately.
  EXPECT_EQ(CONTENT_SETTING_ASK, cache_->CachedDefaultContentSetting());

  // Run IO thread tasks.
  proxy_->DrainIOThread();

  // Now that IO thread events have been processed, it should be there.
  EXPECT_EQ(CONTENT_SETTING_BLOCK, cache_->CachedDefaultContentSetting());
}

TEST_F(DesktopNotificationServiceTest, SettingsForSchemes) {
  GURL url("file:///html/test.html");

  EXPECT_EQ(CONTENT_SETTING_ASK, cache_->CachedDefaultContentSetting());
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, url));

  service_->GrantPermission(url);
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionAllowed,
            proxy_->CacheHasPermission(cache_, url));

  service_->DenyPermission(url);
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionDenied,
            proxy_->CacheHasPermission(cache_, url));

  GURL https_url("https://testurl");
  GURL http_url("http://testurl");
  EXPECT_EQ(CONTENT_SETTING_ASK, cache_->CachedDefaultContentSetting());
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, http_url));
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, https_url));

  service_->GrantPermission(https_url);
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionAllowed,
            proxy_->CacheHasPermission(cache_, https_url));
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, http_url));

  service_->DenyPermission(http_url);
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionDenied,
            proxy_->CacheHasPermission(cache_, http_url));
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionAllowed,
            proxy_->CacheHasPermission(cache_, https_url));
}

TEST_F(DesktopNotificationServiceTest, GrantPermissionSentToCache) {
  GURL url("http://allowed.com");
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, url));

  service_->GrantPermission(url);

  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionAllowed,
            proxy_->CacheHasPermission(cache_, url));
}

TEST_F(DesktopNotificationServiceTest, DenyPermissionSentToCache) {
  GURL url("http://denied.com");
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, url));

  service_->DenyPermission(url);

  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionDenied,
            proxy_->CacheHasPermission(cache_, url));
}

TEST_F(DesktopNotificationServiceTest, PrefChangesSentToCache) {
  PrefService* prefs = profile()->GetPrefs();

  {
    ListPrefUpdate update_allowed_origins(
        prefs, prefs::kDesktopNotificationAllowedOrigins);
    ListValue* allowed_origins = update_allowed_origins.Get();
    allowed_origins->Append(new StringValue(GURL("http://allowed.com").spec()));
  }

  {
    ListPrefUpdate update_denied_origins(
        prefs, prefs::kDesktopNotificationDeniedOrigins);
    ListValue* denied_origins = update_denied_origins.Get();
    denied_origins->Append(new StringValue(GURL("http://denied.com").spec()));
  }

  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionAllowed,
            proxy_->CacheHasPermission(cache_, GURL("http://allowed.com")));
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionDenied,
            proxy_->CacheHasPermission(cache_, GURL("http://denied.com")));
}

TEST_F(DesktopNotificationServiceTest, GetAllowedOrigins) {
  service_->GrantPermission(GURL("http://allowed2.com"));
  service_->GrantPermission(GURL("http://allowed.com"));

  std::vector<GURL> allowed_origins(service_->GetAllowedOrigins());
  ASSERT_EQ(2u, allowed_origins.size());
  EXPECT_EQ(GURL("http://allowed2.com"), allowed_origins[0]);
  EXPECT_EQ(GURL("http://allowed.com"), allowed_origins[1]);
}

TEST_F(DesktopNotificationServiceTest, GetBlockedOrigins) {
  service_->DenyPermission(GURL("http://denied2.com"));
  service_->DenyPermission(GURL("http://denied.com"));

  std::vector<GURL> denied_origins(service_->GetBlockedOrigins());
  ASSERT_EQ(2u, denied_origins.size());
  EXPECT_EQ(GURL("http://denied2.com"), denied_origins[0]);
  EXPECT_EQ(GURL("http://denied.com"), denied_origins[1]);
}

TEST_F(DesktopNotificationServiceTest, ResetAllSentToCache) {
  GURL allowed_url("http://allowed.com");
  service_->GrantPermission(allowed_url);
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionAllowed,
            proxy_->CacheHasPermission(cache_, allowed_url));
  GURL denied_url("http://denied.com");
  service_->DenyPermission(denied_url);
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionDenied,
            proxy_->CacheHasPermission(cache_, denied_url));

  service_->ResetAllOrigins();

  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, allowed_url));
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, denied_url));
}

TEST_F(DesktopNotificationServiceTest, ResetAllowedSentToCache) {
  GURL allowed_url("http://allowed.com");
  service_->GrantPermission(allowed_url);
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionAllowed,
            proxy_->CacheHasPermission(cache_, allowed_url));

  service_->ResetAllowedOrigin(allowed_url);

  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, allowed_url));
}

TEST_F(DesktopNotificationServiceTest, ResetBlockedSentToCache) {
  GURL denied_url("http://denied.com");
  service_->DenyPermission(denied_url);
  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionDenied,
            proxy_->CacheHasPermission(cache_, denied_url));

  service_->ResetBlockedOrigin(denied_url);

  EXPECT_EQ(WebKit::WebNotificationPresenter::PermissionNotAllowed,
            proxy_->CacheHasPermission(cache_, denied_url));
}

}  // namespace
<|endoftext|>


<commit_before>/*
Copyright (C) 2007 <SWGEmu>

This File is part of Core3.

This program is free software; you can redistribute
it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software
Foundation; either version 2 of the License,
or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for
more details.

You should have received a copy of the GNU Lesser General
Public License along with this program; if not, write to
the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Linking Engine3 statically or dynamically with other modules
is making a combined work based on Engine3.
Thus, the terms and conditions of the GNU Lesser General Public License
cover the whole combination.

In addition, as a special exception, the copyright holders of Engine3
give you permission to combine Engine3 program with free software
programs or libraries that are released under the GNU LGPL and with
code included in the standard release of Core3 under the GNU LGPL
license (or modified versions of such code, with unchanged license).
You may copy and distribute such a system following the terms of the
GNU LGPL for Engine3 and the licenses of the other code concerned,
provided that you include the source code of that other code when
and as the GNU LGPL requires distribution of source code.

Note that people who make modified versions of Engine3 are not obligated
to grant this special exception for their modified versions;
it is their choice whether to do so. The GNU Lesser General Public License
gives permission to release a modified version without this exception;
this exception also makes it possible to release a modified version
which carries forward this exception.
*/

#include "server/ServerCore.h"

#include "server/zone/objects/tangible/Container.h"

/*#include "system/mm/AllocationTracker.h"

AllocationTracker* tracker;

void initializeTracker() {
	printf("malloc initialization Hook installed\n");

	tracker = AllocationTracker::getInstance();
	tracker->install();
}*/

//void (*__malloc_initialize_hook)(void) = initializeTracker;

int main(int argc, char* argv[]) {
	try {
		Vector<String> arguments;
		for (int i = 1; i < argc; ++i) {
			arguments.add(argv[i]);
		}

		ServerCore core;

		core.start();

	} catch (Exception& e) {
		System::out << e.getMessage() << "\n";
		e.printStackTrace();
	} catch (...) {
		System::out << "unreported exception caught main()\n";
	}

	return 0;
}

<commit_msg>[fixed] missing file<commit_after>/*
Copyright (C) 2007 <SWGEmu>

This File is part of Core3.

This program is free software; you can redistribute
it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software
Foundation; either version 2 of the License,
or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for
more details.

You should have received a copy of the GNU Lesser General
Public License along with this program; if not, write to
the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Linking Engine3 statically or dynamically with other modules
is making a combined work based on Engine3.
Thus, the terms and conditions of the GNU Lesser General Public License
cover the whole combination.

In addition, as a special exception, the copyright holders of Engine3
give you permission to combine Engine3 program with free software
programs or libraries that are released under the GNU LGPL and with
code included in the standard release of Core3 under the GNU LGPL
license (or modified versions of such code, with unchanged license).
You may copy and distribute such a system following the terms of the
GNU LGPL for Engine3 and the licenses of the other code concerned,
provided that you include the source code of that other code when
and as the GNU LGPL requires distribution of source code.

Note that people who make modified versions of Engine3 are not obligated
to grant this special exception for their modified versions;
it is their choice whether to do so. The GNU Lesser General Public License
gives permission to release a modified version without this exception;
this exception also makes it possible to release a modified version
which carries forward this exception.
*/

#include "server/ServerCore.h"

/*#include "system/mm/AllocationTracker.h"

	AllocationTracker* tracker;

	void initializeTracker() {
	        printf("malloc initialization Hook installed\n");

	        tracker = AllocationTracker::getInstance();
	        tracker->install();
}*/

int main(int argc, char* argv[]) {
	try {
		SortedVector<String> arguments;
		for (int i = 1; i < argc; ++i) {
			arguments.put(argv[i]);
		}

		bool truncateData = arguments.contains("clean");

		ServerCore core(truncateData);

		core.start();

	} catch (Exception& e) {
		System::out << e.getMessage() << "\n";
		e.printStackTrace();
	} catch (...) {
		System::out << "unreported exception caught main()\n";
	}

	return 0;
}

<|endoftext|>


<commit_before>/*
 * Copyright 2010 MQWeb - Franky Braem
 *
 * Licensed under the EUPL, Version 1.1 or – as soon they
 * will be approved by the European Commission - subsequent
 * versions of the EUPL (the "Licence");
 * You may not use this work except in compliance with the
 * Licence.
 * You may obtain a copy of the Licence at:
 *
 * http://joinup.ec.europa.eu/software/page/eupl
 *
 * Unless required by applicable law or agreed to in
 * writing, software distributed under the Licence is
 * distributed on an "AS IS" basis,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the Licence for the specific language governing
 * permissions and limitations under the Licence.
 */
#include <string.h>

#include "Poco/DateTimeParser.h"
#include "Poco/Util/Application.h"
#include "Poco/StringTokenizer.h"

#include "MQ/QueueManager.h"
#include "MQ/MQException.h"
#include "MQ/MQSubsystem.h"

namespace MQ
{
QueueManager::QueueManager(const std::string& name)
:	 _handle(0),
	_name(name),
	_applicationType(0)
{
}

QueueManager::~QueueManager()
{
	if ( _handle != 0 )
	{
		try
		{
			disconnect();
		}
		catch(MQException&)
		{
			// Don't throw exceptions from a destructor
			// See: http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.9
		}
	}
}

void QueueManager::connect()
{
	MQCNO cno = { MQCNO_DEFAULT };
	cno.Version = MQCNO_VERSION_2;
	cno.Options = MQCNO_HANDLE_SHARE_NONE;

	MQ::MQSubsystem& mqSystem = Poco::Util::Application::instance().getSubsystem<MQ::MQSubsystem>();
	_handle = mqSystem.functions().connx(_name, &cno);

	inquireQmgrAttrs();
}

void QueueManager::connect(const std::string& channel, const std::string& server)
{
	MQCNO cno = { MQCNO_DEFAULT };
	cno.Version = MQCNO_VERSION_2;
	cno.Options = MQCNO_HANDLE_SHARE_BLOCK;

	MQCD cd = { MQCD_CLIENT_CONN_DEFAULT };
	strncpy(cd.ChannelName, channel.c_str(), MQ_CHANNEL_NAME_LENGTH);
	strncpy(cd.ConnectionName, server.c_str(), MQ_CONN_NAME_LENGTH);
	cd.TransportType = MQXPT_TCP;
	cno.ClientConnPtr = &cd;

	MQ::MQSubsystem& mqSystem = Poco::Util::Application::instance().getSubsystem<MQ::MQSubsystem>();
	_handle = mqSystem.functions().connx(_name, &cno);

	inquireQmgrAttrs();
}

void QueueManager::connect(const Poco::DynamicStruct& connectionInformation)
{
	if ( connectionInformation.contains("ssl") )
	{
		Poco::Dynamic::Var ssl  = connectionInformation["ssl"];
		if ( ssl.isStruct() )
		{
			connect(connectionInformation["channel"],
				connectionInformation["connection"],
				ssl.extract<Poco::Dynamic::Struct<std::string> >());
		}
	}
	else
	{
		if ( connectionInformation.contains("channel") && connectionInformation.contains("connection") )
		{
			connect(connectionInformation["channel"], connectionInformation["connection"]);
		}
		else
		{
			connect();
		}
	}
}

void QueueManager::connect(const std::string& channel, const std::string& server, const Poco::DynamicStruct& ssl)
{
	MQCNO cno = { MQCNO_DEFAULT };

	/*
	We must specify MQCNO version 4 to ensure that both the client
	connection pointer and SSL configuration options are used
	*/
	cno.Version = MQCNO_VERSION_4;
	cno.Options = MQCNO_HANDLE_SHARE_BLOCK;

	MQCD cd = { MQCD_CLIENT_CONN_DEFAULT };
	strncpy(cd.ChannelName, channel.c_str(), MQ_CHANNEL_NAME_LENGTH);
	strncpy(cd.ConnectionName, server.c_str(), MQ_CONN_NAME_LENGTH);

	if ( ssl.contains("cipherspec") )
	{
		strncpy(cd.SSLCipherSpec, ssl["cipherspec"].toString().c_str(), MQ_SSL_CIPHER_SPEC_LENGTH);
		cd.Version = MQCD_VERSION_7; // SSL requires MQCD version 7 or later
	}

	cd.TransportType = MQXPT_TCP;
	cno.ClientConnPtr = &cd;

	MQSCO sco = { MQSCO_DEFAULT };
	MQAIR authInfoRec = { MQAIR_DEFAULT };

	Poco::Dynamic::Var keyrepos = ssl["keyrepos"];
	strncpy(sco.KeyRepository, keyrepos.toString().c_str(), MQ_SSL_KEY_REPOSITORY_LENGTH);

	if ( ssl.contains("fips") )
	{
		if ( ssl["fips"].convert<bool>() )
		{
			sco.FipsRequired = MQSSL_FIPS_YES;
			sco.Version = MQSCO_VERSION_2; // A version 2 MQSCO supports FipsRequired
		}
	}

	if ( ssl.contains("suiteb") )
	{
		static std::map<std::string, MQLONG> suiteBTable;
		if ( suiteBTable.size() == 0 )
		{
			suiteBTable.insert(std::make_pair<std::string, MQLONG>("none", MQ_SUITE_B_NONE));
			suiteBTable.insert(std::make_pair<std::string, MQLONG>("128 bit", MQ_SUITE_B_128_BIT));
			suiteBTable.insert(std::make_pair<std::string, MQLONG>("192 bit", MQ_SUITE_B_192_BIT));
		}

		sco.Version = MQSCO_VERSION_3; /* A version 3 MQSCO supports Suite B encryption policy */

		Poco::StringTokenizer tokenizer(ssl["suiteb"].toString(), ",", Poco::StringTokenizer::TOK_TRIM);
		int n = 0;
		for(Poco::StringTokenizer::Iterator it = tokenizer.begin(); it != tokenizer.end() && n < 4; ++it, ++n)
		{
			std::map<std::string, MQLONG>::iterator suiteBIterator = suiteBTable.find(*it);
			if ( suiteBIterator == suiteBTable.end() )
			{
				throw Poco::NotFoundException(Poco::format("Unknown SuiteB value: %s", *it));
			}
			else
			{
				sco.EncryptionPolicySuiteB[n] = suiteBIterator->second;
			}
		}
	}

#ifdef MQSCO_VERSION_4
	if ( ssl.contains("certificate_validation_policy") )
	{
		static std::map<std::string, MQLONG> certValPolicyTable;
		if ( certValPolicyTable.size() == 0 )
		{
			certValPolicyTable.insert(std::make_pair<std::string, MQLONG>("any", MQ_CERT_VAL_POLICY_ANY));
			certValPolicyTable.insert(std::make_pair<std::string, MQLONG>("rfc5280", MQ_CERT_VAL_POLICY_RFC5280));
		}

		sco.Version = MQSCO_VERSION_4; /* A version 4 MQSCO supports certificate validation policy */

		std::string certValPolicy = ssl["certificate_validation_policy"].toString();
		std::map<std::string, MQLONG>::iterator certValPolicyIterator = certValPolicyTable.find(certValPolicy);
		if ( certValPolicyIterator == certValPolicyTable.end() )
		{
			throw Poco::NotFoundException(Poco::format("Unknown Certification Validation Policy: %s", certValPolicy));
		}
		else
		{
			sco.CertificateValPolicy = certValPolicyIterator->second;
		}
	}
#endif
	if ( ssl.contains("ocsp_url") )
	{
		/* OCSP requires MQAIR version 2 or later */
		authInfoRec.Version = MQAIR_VERSION_2;
		authInfoRec.AuthInfoType = MQAIT_OCSP;

		strncpy(authInfoRec.OCSPResponderURL, ssl["ocsp_url"].toString().c_str(), MQ_AUTH_INFO_OCSP_URL_LENGTH);

		/* The MQSCO must point to the MQAIR */
		sco.AuthInfoRecCount = 1;
		sco.AuthInfoRecPtr = &authInfoRec;
	}

	cno.SSLConfigPtr = &sco;

	MQ::MQSubsystem& mqSystem = Poco::Util::Application::instance().getSubsystem<MQ::MQSubsystem>();
	_handle = mqSystem.functions().connx(_name, &cno);

	inquireQmgrAttrs();
}

void QueueManager::inquireQmgrAttrs()
{
	MQ::MQSubsystem& mqSystem = Poco::Util::Application::instance().getSubsystem<MQ::MQSubsystem>();

	MQOD qmgrObjectDesc = {MQOD_DEFAULT};
	qmgrObjectDesc.ObjectType = MQOT_Q_MGR;
	MQHOBJ qmgrObjectHandle = mqSystem.functions().open(_handle, &qmgrObjectDesc, MQOO_INQUIRE);

	std::vector<int> intSelectors;
	intSelectors.push_back(MQIA_PLATFORM);

	std::map<int, int> charSelectors;
	charSelectors[MQCA_Q_MGR_NAME] = MQ_Q_MGR_NAME_LENGTH;
	charSelectors[MQCA_Q_MGR_IDENTIFIER] = MQ_Q_MGR_IDENTIFIER_LENGTH;
	charSelectors[MQCA_COMMAND_INPUT_Q_NAME] = MQ_Q_NAME_LENGTH;

	std::map<int, int> intResult;
	std::map<int, std::string> charResult;
	mqSystem.functions().inq(_handle, qmgrObjectHandle, intSelectors, charSelectors, intResult, charResult);

	_applicationType = intResult[MQIA_PLATFORM];
	_name = charResult[MQCA_Q_MGR_NAME];
	_id = charResult[MQCA_Q_MGR_IDENTIFIER];
	_commandQueue = charResult[MQCA_COMMAND_INPUT_Q_NAME];

	mqSystem.functions().close(_handle, &qmgrObjectHandle, MQCO_NONE);
}

void QueueManager::disconnect()
{
	if ( _handle != 0 )
	{
		MQ::MQSubsystem& mqSystem = Poco::Util::Application::instance().getSubsystem<MQ::MQSubsystem>();
		mqSystem.functions().disc(&_handle);
		_handle = 0;
	}
}

}
<commit_msg>Options in connect must be MQCNO_HANDLE_SHARE_BLOCK<commit_after>/*
 * Copyright 2010 MQWeb - Franky Braem
 *
 * Licensed under the EUPL, Version 1.1 or – as soon they
 * will be approved by the European Commission - subsequent
 * versions of the EUPL (the "Licence");
 * You may not use this work except in compliance with the
 * Licence.
 * You may obtain a copy of the Licence at:
 *
 * http://joinup.ec.europa.eu/software/page/eupl
 *
 * Unless required by applicable law or agreed to in
 * writing, software distributed under the Licence is
 * distributed on an "AS IS" basis,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the Licence for the specific language governing
 * permissions and limitations under the Licence.
 */
#include <string.h>

#include "Poco/DateTimeParser.h"
#include "Poco/Util/Application.h"
#include "Poco/StringTokenizer.h"

#include "MQ/QueueManager.h"
#include "MQ/MQException.h"
#include "MQ/MQSubsystem.h"

namespace MQ
{
QueueManager::QueueManager(const std::string& name)
:	 _handle(0),
	_name(name),
	_applicationType(0)
{
}

QueueManager::~QueueManager()
{
	if ( _handle != 0 )
	{
		try
		{
			disconnect();
		}
		catch(MQException&)
		{
			// Don't throw exceptions from a destructor
			// See: http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.9
		}
	}
}

void QueueManager::connect()
{
	MQCNO cno = { MQCNO_DEFAULT };
	cno.Version = MQCNO_VERSION_2;
	cno.Options = MQCNO_HANDLE_SHARE_BLOCK;

	MQ::MQSubsystem& mqSystem = Poco::Util::Application::instance().getSubsystem<MQ::MQSubsystem>();
	_handle = mqSystem.functions().connx(_name, &cno);

	inquireQmgrAttrs();
}

void QueueManager::connect(const std::string& channel, const std::string& server)
{
	MQCNO cno = { MQCNO_DEFAULT };
	cno.Version = MQCNO_VERSION_2;
	cno.Options = MQCNO_HANDLE_SHARE_BLOCK;

	MQCD cd = { MQCD_CLIENT_CONN_DEFAULT };
	strncpy(cd.ChannelName, channel.c_str(), MQ_CHANNEL_NAME_LENGTH);
	strncpy(cd.ConnectionName, server.c_str(), MQ_CONN_NAME_LENGTH);
	cd.TransportType = MQXPT_TCP;
	cno.ClientConnPtr = &cd;

	MQ::MQSubsystem& mqSystem = Poco::Util::Application::instance().getSubsystem<MQ::MQSubsystem>();
	_handle = mqSystem.functions().connx(_name, &cno);

	inquireQmgrAttrs();
}

void QueueManager::connect(const Poco::DynamicStruct& connectionInformation)
{
	if ( connectionInformation.contains("ssl") )
	{
		Poco::Dynamic::Var ssl  = connectionInformation["ssl"];
		if ( ssl.isStruct() )
		{
			connect(connectionInformation["channel"],
				connectionInformation["connection"],
				ssl.extract<Poco::Dynamic::Struct<std::string> >());
		}
	}
	else
	{
		if ( connectionInformation.contains("channel") && connectionInformation.contains("connection") )
		{
			connect(connectionInformation["channel"], connectionInformation["connection"]);
		}
		else
		{
			connect();
		}
	}
}

void QueueManager::connect(const std::string& channel, const std::string& server, const Poco::DynamicStruct& ssl)
{
	MQCNO cno = { MQCNO_DEFAULT };

	/*
	We must specify MQCNO version 4 to ensure that both the client
	connection pointer and SSL configuration options are used
	*/
	cno.Version = MQCNO_VERSION_4;
	cno.Options = MQCNO_HANDLE_SHARE_BLOCK;

	MQCD cd = { MQCD_CLIENT_CONN_DEFAULT };
	strncpy(cd.ChannelName, channel.c_str(), MQ_CHANNEL_NAME_LENGTH);
	strncpy(cd.ConnectionName, server.c_str(), MQ_CONN_NAME_LENGTH);

	if ( ssl.contains("cipherspec") )
	{
		strncpy(cd.SSLCipherSpec, ssl["cipherspec"].toString().c_str(), MQ_SSL_CIPHER_SPEC_LENGTH);
		cd.Version = MQCD_VERSION_7; // SSL requires MQCD version 7 or later
	}

	cd.TransportType = MQXPT_TCP;
	cno.ClientConnPtr = &cd;

	MQSCO sco = { MQSCO_DEFAULT };
	MQAIR authInfoRec = { MQAIR_DEFAULT };

	Poco::Dynamic::Var keyrepos = ssl["keyrepos"];
	strncpy(sco.KeyRepository, keyrepos.toString().c_str(), MQ_SSL_KEY_REPOSITORY_LENGTH);

	if ( ssl.contains("fips") )
	{
		if ( ssl["fips"].convert<bool>() )
		{
			sco.FipsRequired = MQSSL_FIPS_YES;
			sco.Version = MQSCO_VERSION_2; // A version 2 MQSCO supports FipsRequired
		}
	}

	if ( ssl.contains("suiteb") )
	{
		static std::map<std::string, MQLONG> suiteBTable;
		if ( suiteBTable.size() == 0 )
		{
			suiteBTable.insert(std::make_pair<std::string, MQLONG>("none", MQ_SUITE_B_NONE));
			suiteBTable.insert(std::make_pair<std::string, MQLONG>("128 bit", MQ_SUITE_B_128_BIT));
			suiteBTable.insert(std::make_pair<std::string, MQLONG>("192 bit", MQ_SUITE_B_192_BIT));
		}

		sco.Version = MQSCO_VERSION_3; /* A version 3 MQSCO supports Suite B encryption policy */

		Poco::StringTokenizer tokenizer(ssl["suiteb"].toString(), ",", Poco::StringTokenizer::TOK_TRIM);
		int n = 0;
		for(Poco::StringTokenizer::Iterator it = tokenizer.begin(); it != tokenizer.end() && n < 4; ++it, ++n)
		{
			std::map<std::string, MQLONG>::iterator suiteBIterator = suiteBTable.find(*it);
			if ( suiteBIterator == suiteBTable.end() )
			{
				throw Poco::NotFoundException(Poco::format("Unknown SuiteB value: %s", *it));
			}
			else
			{
				sco.EncryptionPolicySuiteB[n] = suiteBIterator->second;
			}
		}
	}

#ifdef MQSCO_VERSION_4
	if ( ssl.contains("certificate_validation_policy") )
	{
		static std::map<std::string, MQLONG> certValPolicyTable;
		if ( certValPolicyTable.size() == 0 )
		{
			certValPolicyTable.insert(std::make_pair<std::string, MQLONG>("any", MQ_CERT_VAL_POLICY_ANY));
			certValPolicyTable.insert(std::make_pair<std::string, MQLONG>("rfc5280", MQ_CERT_VAL_POLICY_RFC5280));
		}

		sco.Version = MQSCO_VERSION_4; /* A version 4 MQSCO supports certificate validation policy */

		std::string certValPolicy = ssl["certificate_validation_policy"].toString();
		std::map<std::string, MQLONG>::iterator certValPolicyIterator = certValPolicyTable.find(certValPolicy);
		if ( certValPolicyIterator == certValPolicyTable.end() )
		{
			throw Poco::NotFoundException(Poco::format("Unknown Certification Validation Policy: %s", certValPolicy));
		}
		else
		{
			sco.CertificateValPolicy = certValPolicyIterator->second;
		}
	}
#endif
	if ( ssl.contains("ocsp_url") )
	{
		/* OCSP requires MQAIR version 2 or later */
		authInfoRec.Version = MQAIR_VERSION_2;
		authInfoRec.AuthInfoType = MQAIT_OCSP;

		strncpy(authInfoRec.OCSPResponderURL, ssl["ocsp_url"].toString().c_str(), MQ_AUTH_INFO_OCSP_URL_LENGTH);

		/* The MQSCO must point to the MQAIR */
		sco.AuthInfoRecCount = 1;
		sco.AuthInfoRecPtr = &authInfoRec;
	}

	cno.SSLConfigPtr = &sco;

	MQ::MQSubsystem& mqSystem = Poco::Util::Application::instance().getSubsystem<MQ::MQSubsystem>();
	_handle = mqSystem.functions().connx(_name, &cno);

	inquireQmgrAttrs();
}

void QueueManager::inquireQmgrAttrs()
{
	MQ::MQSubsystem& mqSystem = Poco::Util::Application::instance().getSubsystem<MQ::MQSubsystem>();

	MQOD qmgrObjectDesc = {MQOD_DEFAULT};
	qmgrObjectDesc.ObjectType = MQOT_Q_MGR;
	MQHOBJ qmgrObjectHandle = mqSystem.functions().open(_handle, &qmgrObjectDesc, MQOO_INQUIRE);

	std::vector<int> intSelectors;
	intSelectors.push_back(MQIA_PLATFORM);

	std::map<int, int> charSelectors;
	charSelectors[MQCA_Q_MGR_NAME] = MQ_Q_MGR_NAME_LENGTH;
	charSelectors[MQCA_Q_MGR_IDENTIFIER] = MQ_Q_MGR_IDENTIFIER_LENGTH;
	charSelectors[MQCA_COMMAND_INPUT_Q_NAME] = MQ_Q_NAME_LENGTH;

	std::map<int, int> intResult;
	std::map<int, std::string> charResult;
	mqSystem.functions().inq(_handle, qmgrObjectHandle, intSelectors, charSelectors, intResult, charResult);

	_applicationType = intResult[MQIA_PLATFORM];
	_name = charResult[MQCA_Q_MGR_NAME];
	_id = charResult[MQCA_Q_MGR_IDENTIFIER];
	_commandQueue = charResult[MQCA_COMMAND_INPUT_Q_NAME];

	mqSystem.functions().close(_handle, &qmgrObjectHandle, MQCO_NONE);
}

void QueueManager::disconnect()
{
	if ( _handle != 0 )
	{
		MQ::MQSubsystem& mqSystem = Poco::Util::Application::instance().getSubsystem<MQ::MQSubsystem>();
		mqSystem.functions().disc(&_handle);
		_handle = 0;
	}
}

}
<|endoftext|>