<commit_before>/******************************************************************************\
 *           ___        __                                                    *
 *          /\_ \    __/\ \                                                   *
 *          \//\ \  /\_\ \ \____    ___   _____   _____      __               *
 *            \ \ \ \/\ \ \ '__`\  /'___\/\ '__`\/\ '__`\  /'__`\             *
 *             \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_           *
 *             /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\          *
 *             \/____/ \/_/\/___/  \/____/ \ \ \/  \ \ \/  \/__/\/_/          *
 *                                          \ \_\   \ \_\                     *
 *                                           \/_/    \/_/                     *
 *                                                                            *
 * Copyright (C) 2011-2013                                                    *
 * Dominik Charousset <dominik.charousset@haw-hamburg.de>                     *
 * Raphael Hiesgen <raphael.hiesgen@haw-hamburg.de>                           *
 *                                                                            *
 * This file is part of libcppa.                                              *
 * libcppa 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.1 of the License,               *
 * or (at your option) any later version.                                     *
 *                                                                            *
 * libcppa 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 libcppa. If not, see <http://www.gnu.org/licenses/>.            *
\******************************************************************************/

#ifndef CPPA_OPENCL_ACTOR_FACADE_HPP
#define CPPA_OPENCL_ACTOR_FACADE_HPP

#include <ostream>
#include <algorithm>
#include <stdexcept>

#include "cppa/cppa.hpp"

#include "cppa/channel.hpp"
#include "cppa/to_string.hpp"
#include "cppa/tuple_cast.hpp"
#include "cppa/intrusive_ptr.hpp"

#include "cppa/util/int_list.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/limited_vector.hpp"

#include "cppa/opencl/global.hpp"
#include "cppa/opencl/command.hpp"
#include "cppa/opencl/program.hpp"
#include "cppa/opencl/smart_ptr.hpp"

#include "cppa/detail/scheduled_actor_dummy.hpp"

namespace cppa { namespace opencl {

class command_dispatcher;

void enqueue_to_dispatcher(command_dispatcher*, command_ptr);

template<typename Signature>
class actor_facade;

template<typename Ret, typename... Args>
class actor_facade<Ret(Args...)> : public actor {

 public:

    typedef cow_tuple<typename util::rm_ref<Args>::type...> args_tuple;
    typedef std::function<option<args_tuple>(any_tuple)> arg_mapping;
    typedef std::function<any_tuple(Ret&)> result_mapping;

    static actor_facade* create(command_dispatcher* dispatcher,
                               const program& prog,
                               const char* kernel_name,
                               const dim_vec& global_dims,
                               const dim_vec& offsets,
                               const dim_vec& local_dims,
                               arg_mapping map_args,
                               result_mapping map_result) {
        if (global_dims.empty()) {
            auto str = "OpenCL kernel needs at least 1 global dimension.";
            CPPA_LOGM_ERROR(detail::demangle(typeid(actor_facade)), str);
            throw std::runtime_error(str);
        }
        auto check_vec = [&](const dim_vec& vec, const char* name) {
            if (!vec.empty() && vec.size() != global_dims.size()) {
                std::ostringstream oss;
                oss << name << " vector is not empty, but "
                    << "its size differs from global dimensions vector's size";
                CPPA_LOGM_ERROR(detail::demangle<actor_facade>(), oss.str());
                throw std::runtime_error(oss.str());
            }
        };
        check_vec(offsets, "offsets");
        check_vec(local_dims, "local dimensions");
        cl_int err{0};
        kernel_ptr kernel;
        kernel.adopt(clCreateKernel(prog.m_program.get(),
                                    kernel_name,
                                    &err));
        if (err != CL_SUCCESS) {
            std::ostringstream oss;
            oss << "clCreateKernel: " << get_opencl_error(err);
            CPPA_LOGM_ERROR(detail::demangle<actor_facade>(), oss.str());
            throw std::runtime_error(oss.str());
        }
        return new actor_facade<Ret (Args...)>{dispatcher,
                                               kernel,
                                               prog,
                                               global_dims,
                                               offsets,
                                               local_dims,
                                               std::move(map_args),
                                               std::move(map_result)};
    }

    void sync_enqueue(const actor_ptr& sender, message_id id, any_tuple msg) override {
        CPPA_LOG_TRACE("");
        typename util::il_indices<util::type_list<Args...>>::type indices;
        enqueue_impl(sender, msg, id, indices);
    }

    void enqueue(const actor_ptr& sender, any_tuple msg) override {
        CPPA_LOG_TRACE("");
        typename util::il_indices<util::type_list<Args...>>::type indices;
        enqueue_impl(sender, msg, message_id{}, indices);
    }

 private:

    actor_facade(command_dispatcher* dispatcher,
                 kernel_ptr kernel,
                 const program& prog,
                 const dim_vec& global_dimensions,
                 const dim_vec& global_offsets,
                 const dim_vec& local_dimensions,
                 arg_mapping map_args,
                 result_mapping map_result)
      : m_kernel(kernel)
      , m_program(prog.m_program)
      , m_context(prog.m_context)
      , m_dispatcher(dispatcher)
      , m_global_dimensions(global_dimensions)
      , m_global_offsets(global_offsets)
      , m_local_dimensions(local_dimensions)
      , m_map_args(std::move(map_args))
      , m_map_result(std::move(map_result))
    {
        CPPA_LOG_TRACE("id: " << this->id());
    }

    template<long... Is>
    void enqueue_impl(const actor_ptr& sender, any_tuple msg, message_id id, util::int_list<Is...>) {
        auto opt = m_map_args(msg);
        if (opt) {
            response_handle handle{this, sender, id.response_id()};
            Ret result_buf(std::accumulate(m_global_dimensions.begin(),
                                           m_global_dimensions.end(),
                                           1, std::multiplies<size_t>{}));
            std::vector<mem_ptr> arguments;
            add_arguments_to_kernel(arguments,
                                    m_context.get(),
                                    m_kernel.get(),
                                    result_buf,
                                    get_ref<Is>(*opt)...);
            enqueue_to_dispatcher(m_dispatcher,
                                  make_counted<command_impl<Ret>>(handle,
                                                                  m_kernel,
                                                                  std::move(arguments),
                                                                  m_global_dimensions,
                                                                  m_global_offsets,
                                                                  m_local_dimensions,
                                                                  m_map_result));
        }
        else { CPPA_LOG_ERROR("actor_facade::enqueue() tuple_cast failed."); }
    }

    typedef std::vector<mem_ptr> args_vec;

    kernel_ptr m_kernel;
    program_ptr m_program;
    context_ptr m_context;
    command_dispatcher* m_dispatcher;
    dim_vec m_global_dimensions;
    dim_vec m_global_offsets;
    dim_vec m_local_dimensions;
    arg_mapping m_map_args;
    result_mapping m_map_result;

    void add_arguments_to_kernel_rec(args_vec& arguments,
                                     cl_context,
                                     cl_kernel kernel) {
        cl_int err{0};
        for(size_t i = 1; i < arguments.size(); ++i) {
            err = clSetKernelArg(kernel,
                                 (i-1),
                                 sizeof(cl_mem),
                                 static_cast<void*>(&arguments[i]));
            CPPA_LOG_ERROR_IF(err != CL_SUCCESS,
                              "clSetKernelArg: " << get_opencl_error(err));
        }
        err = clSetKernelArg(kernel,
                             arguments.size()-1,
                             sizeof(cl_mem),
                             static_cast<void*>(&arguments[0]));
        CPPA_LOG_ERROR_IF(err != CL_SUCCESS,
                          "clSetKernelArg: " << get_opencl_error(err));
    }

    template<typename T0, typename... Ts>
    void add_arguments_to_kernel_rec(args_vec& arguments,
                                     cl_context context,
                                     cl_kernel kernel,
                                     T0& arg0,
                                     Ts&... args) {
        cl_int err{0};
        auto buf = clCreateBuffer(context,
                                  CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
                                  sizeof(typename T0::value_type) * arg0.size(),
                                  arg0.data(),
                                  &err);
        if (err != CL_SUCCESS) {
            CPPA_LOG_ERROR("clCreateBuffer: " << get_opencl_error(err));
        }
        else {
            mem_ptr tmp;
            tmp.adopt(std::move(buf));
            arguments.push_back(tmp);
            add_arguments_to_kernel_rec(arguments, context, kernel, args...);
        }
    }

    template<typename R, typename... Ts>
    void add_arguments_to_kernel(args_vec& arguments,
                                 cl_context context,
                                 cl_kernel kernel,
                                 R& ret,
                                 Ts&&... args) {
        arguments.clear();
        cl_int err{0};
        auto buf = clCreateBuffer(context,
                                  CL_MEM_WRITE_ONLY,
                                  sizeof(typename R::value_type) * ret.size(),
                                  nullptr,
                                  &err);
        if (err != CL_SUCCESS) {
            CPPA_LOG_ERROR("clCreateBuffer: " << get_opencl_error(err));
        }
        else {
            mem_ptr tmp;
            tmp.adopt(std::move(buf));
            arguments.push_back(tmp);
            add_arguments_to_kernel_rec(arguments,
                                        context,
                                        kernel,
                                        std::forward<Ts>(args)...);
        }
    }

};

} } // namespace cppa::opencl

#endif // CPPA_OPENCL_ACTOR_FACADE_HPP
<commit_msg>use message headers instead of different enqueues<commit_after>/******************************************************************************\
 *           ___        __                                                    *
 *          /\_ \    __/\ \                                                   *
 *          \//\ \  /\_\ \ \____    ___   _____   _____      __               *
 *            \ \ \ \/\ \ \ '__`\  /'___\/\ '__`\/\ '__`\  /'__`\             *
 *             \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_           *
 *             /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\          *
 *             \/____/ \/_/\/___/  \/____/ \ \ \/  \ \ \/  \/__/\/_/          *
 *                                          \ \_\   \ \_\                     *
 *                                           \/_/    \/_/                     *
 *                                                                            *
 * Copyright (C) 2011-2013                                                    *
 * Dominik Charousset <dominik.charousset@haw-hamburg.de>                     *
 * Raphael Hiesgen <raphael.hiesgen@haw-hamburg.de>                           *
 *                                                                            *
 * This file is part of libcppa.                                              *
 * libcppa 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.1 of the License,               *
 * or (at your option) any later version.                                     *
 *                                                                            *
 * libcppa 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 libcppa. If not, see <http://www.gnu.org/licenses/>.            *
\******************************************************************************/

#ifndef CPPA_OPENCL_ACTOR_FACADE_HPP
#define CPPA_OPENCL_ACTOR_FACADE_HPP

#include <ostream>
#include <algorithm>
#include <stdexcept>

#include "cppa/cppa.hpp"

#include "cppa/channel.hpp"
#include "cppa/to_string.hpp"
#include "cppa/tuple_cast.hpp"
#include "cppa/intrusive_ptr.hpp"

#include "cppa/util/int_list.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/limited_vector.hpp"

#include "cppa/opencl/global.hpp"
#include "cppa/opencl/command.hpp"
#include "cppa/opencl/program.hpp"
#include "cppa/opencl/smart_ptr.hpp"

#include "cppa/detail/scheduled_actor_dummy.hpp"

namespace cppa { namespace opencl {

class command_dispatcher;

void enqueue_to_dispatcher(command_dispatcher*, command_ptr);

template<typename Signature>
class actor_facade;

template<typename Ret, typename... Args>
class actor_facade<Ret(Args...)> : public actor {

 public:

    typedef cow_tuple<typename util::rm_ref<Args>::type...> args_tuple;
    typedef std::function<option<args_tuple>(any_tuple)> arg_mapping;
    typedef std::function<any_tuple(Ret&)> result_mapping;

    static actor_facade* create(command_dispatcher* dispatcher,
                               const program& prog,
                               const char* kernel_name,
                               const dim_vec& global_dims,
                               const dim_vec& offsets,
                               const dim_vec& local_dims,
                               arg_mapping map_args,
                               result_mapping map_result) {
        if (global_dims.empty()) {
            auto str = "OpenCL kernel needs at least 1 global dimension.";
            CPPA_LOGM_ERROR(detail::demangle(typeid(actor_facade)), str);
            throw std::runtime_error(str);
        }
        auto check_vec = [&](const dim_vec& vec, const char* name) {
            if (!vec.empty() && vec.size() != global_dims.size()) {
                std::ostringstream oss;
                oss << name << " vector is not empty, but "
                    << "its size differs from global dimensions vector's size";
                CPPA_LOGM_ERROR(detail::demangle<actor_facade>(), oss.str());
                throw std::runtime_error(oss.str());
            }
        };
        check_vec(offsets, "offsets");
        check_vec(local_dims, "local dimensions");
        cl_int err{0};
        kernel_ptr kernel;
        kernel.adopt(clCreateKernel(prog.m_program.get(),
                                    kernel_name,
                                    &err));
        if (err != CL_SUCCESS) {
            std::ostringstream oss;
            oss << "clCreateKernel: " << get_opencl_error(err);
            CPPA_LOGM_ERROR(detail::demangle<actor_facade>(), oss.str());
            throw std::runtime_error(oss.str());
        }
        return new actor_facade<Ret (Args...)>{dispatcher,
                                               kernel,
                                               prog,
                                               global_dims,
                                               offsets,
                                               local_dims,
                                               std::move(map_args),
                                               std::move(map_result)};
    }

    void enqueue(const message_header& hdr, any_tuple msg) override {
        CPPA_LOG_TRACE("");
        typename util::il_indices<util::type_list<Args...>>::type indices;
        enqueue_impl(hdr.sender, msg, hdr.id, indices);
    }

 private:

    actor_facade(command_dispatcher* dispatcher,
                 kernel_ptr kernel,
                 const program& prog,
                 const dim_vec& global_dimensions,
                 const dim_vec& global_offsets,
                 const dim_vec& local_dimensions,
                 arg_mapping map_args,
                 result_mapping map_result)
      : m_kernel(kernel)
      , m_program(prog.m_program)
      , m_context(prog.m_context)
      , m_dispatcher(dispatcher)
      , m_global_dimensions(global_dimensions)
      , m_global_offsets(global_offsets)
      , m_local_dimensions(local_dimensions)
      , m_map_args(std::move(map_args))
      , m_map_result(std::move(map_result))
    {
        CPPA_LOG_TRACE("id: " << this->id());
    }

    template<long... Is>
    void enqueue_impl(const actor_ptr& sender, any_tuple msg, message_id id, util::int_list<Is...>) {
        auto opt = m_map_args(msg);
        if (opt) {
            response_handle handle{this, sender, id.response_id()};
            Ret result_buf(std::accumulate(m_global_dimensions.begin(),
                                           m_global_dimensions.end(),
                                           1, std::multiplies<size_t>{}));
            std::vector<mem_ptr> arguments;
            add_arguments_to_kernel(arguments,
                                    m_context.get(),
                                    m_kernel.get(),
                                    result_buf,
                                    get_ref<Is>(*opt)...);
            enqueue_to_dispatcher(m_dispatcher,
                                  make_counted<command_impl<Ret>>(handle,
                                                                  m_kernel,
                                                                  std::move(arguments),
                                                                  m_global_dimensions,
                                                                  m_global_offsets,
                                                                  m_local_dimensions,
                                                                  m_map_result));
        }
        else { CPPA_LOG_ERROR("actor_facade::enqueue() tuple_cast failed."); }
    }

    typedef std::vector<mem_ptr> args_vec;

    kernel_ptr m_kernel;
    program_ptr m_program;
    context_ptr m_context;
    command_dispatcher* m_dispatcher;
    dim_vec m_global_dimensions;
    dim_vec m_global_offsets;
    dim_vec m_local_dimensions;
    arg_mapping m_map_args;
    result_mapping m_map_result;

    void add_arguments_to_kernel_rec(args_vec& arguments,
                                     cl_context,
                                     cl_kernel kernel) {
        cl_int err{0};
        for(size_t i = 1; i < arguments.size(); ++i) {
            err = clSetKernelArg(kernel,
                                 (i-1),
                                 sizeof(cl_mem),
                                 static_cast<void*>(&arguments[i]));
            CPPA_LOG_ERROR_IF(err != CL_SUCCESS,
                              "clSetKernelArg: " << get_opencl_error(err));
        }
        err = clSetKernelArg(kernel,
                             arguments.size()-1,
                             sizeof(cl_mem),
                             static_cast<void*>(&arguments[0]));
        CPPA_LOG_ERROR_IF(err != CL_SUCCESS,
                          "clSetKernelArg: " << get_opencl_error(err));
    }

    template<typename T0, typename... Ts>
    void add_arguments_to_kernel_rec(args_vec& arguments,
                                     cl_context context,
                                     cl_kernel kernel,
                                     T0& arg0,
                                     Ts&... args) {
        cl_int err{0};
        auto buf = clCreateBuffer(context,
                                  CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
                                  sizeof(typename T0::value_type) * arg0.size(),
                                  arg0.data(),
                                  &err);
        if (err != CL_SUCCESS) {
            CPPA_LOG_ERROR("clCreateBuffer: " << get_opencl_error(err));
        }
        else {
            mem_ptr tmp;
            tmp.adopt(std::move(buf));
            arguments.push_back(tmp);
            add_arguments_to_kernel_rec(arguments, context, kernel, args...);
        }
    }

    template<typename R, typename... Ts>
    void add_arguments_to_kernel(args_vec& arguments,
                                 cl_context context,
                                 cl_kernel kernel,
                                 R& ret,
                                 Ts&&... args) {
        arguments.clear();
        cl_int err{0};
        auto buf = clCreateBuffer(context,
                                  CL_MEM_WRITE_ONLY,
                                  sizeof(typename R::value_type) * ret.size(),
                                  nullptr,
                                  &err);
        if (err != CL_SUCCESS) {
            CPPA_LOG_ERROR("clCreateBuffer: " << get_opencl_error(err));
        }
        else {
            mem_ptr tmp;
            tmp.adopt(std::move(buf));
            arguments.push_back(tmp);
            add_arguments_to_kernel_rec(arguments,
                                        context,
                                        kernel,
                                        std::forward<Ts>(args)...);
        }
    }

};

} } // namespace cppa::opencl

#endif // CPPA_OPENCL_ACTOR_FACADE_HPP
<|endoftext|>


<commit_before>/* mbed Microcontroller Library
 * Copyright (c) 2006-2013 ARM Limited
 *
 * 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.
 */

#include "nRF51GattServer.h"
#include "mbed.h"

#include "common/common.h"
#include "btle/custom/custom_helper.h"

#include "hw/nRF51822n/nRF51Gap.h"

/**************************************************************************/
/*!
    @brief  Adds a new service to the GATT table on the peripheral

    @returns    ble_error_t

    @retval     BLE_ERROR_NONE
                Everything executed properly

    @section EXAMPLE

    @code

    @endcode
*/
/**************************************************************************/
ble_error_t nRF51GattServer::addService(GattService & service)
{
    /* ToDo: Make sure we don't overflow the array, etc. */
    /* ToDo: Make sure this service UUID doesn't already exist (?) */
    /* ToDo: Basic validation */

    /* Add the service to the nRF51 */
    ble_uuid_t uuid;

    if (service.primaryServiceID.type == UUID::UUID_TYPE_SHORT)
    {
      /* 16-bit BLE UUID */
      uuid.type = BLE_UUID_TYPE_BLE;
    }
    else
    {
      /* 128-bit Custom UUID */
      uuid.type = custom_add_uuid_base( service.primaryServiceID.base );
    }

    uuid.uuid = service.primaryServiceID.value;

    ASSERT( ERROR_NONE == sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &uuid, &service.handle), BLE_ERROR_PARAM_OUT_OF_RANGE );

    /* Add characteristics to the service */
    for (uint8_t i = 0; i < service.characteristicCount; i++)
    {
      GattCharacteristic * p_char = service.characteristics[i];

      uuid.uuid = p_char->uuid;
      ASSERT ( ERROR_NONE == custom_add_in_characteristic(service.handle, &uuid, p_char->properties,
                                                          NULL, p_char->lenMin, p_char->lenMax, &nrfCharacteristicHandles[characteristicCount]), BLE_ERROR_PARAM_OUT_OF_RANGE );

      /* Update the characteristic handle */
      p_char->handle = characteristicCount;
      p_characteristics[characteristicCount++] = p_char;
    }

    serviceCount++;

    return BLE_ERROR_NONE;
}

/**************************************************************************/
/*!
    @brief  Reads the value of a characteristic, based on the service
            and characteristic index fields

    @param[in]  charHandle
                The handle of the GattCharacteristic to read from
    @param[in]  buffer
                Buffer to hold the the characteristic's value
                (raw byte array in LSB format)
    @param[in]  len
                The number of bytes read into the buffer

    @returns    ble_error_t

    @retval     BLE_ERROR_NONE
                Everything executed properly

    @section EXAMPLE

    @code

    @endcode
*/
/**************************************************************************/
ble_error_t nRF51GattServer::readValue(uint16_t charHandle, uint8_t buffer[], uint16_t len)
{
    ASSERT( ERROR_NONE == sd_ble_gatts_value_get(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), BLE_ERROR_PARAM_OUT_OF_RANGE);

    return BLE_ERROR_NONE;
}

/**************************************************************************/
/*!
    @brief  Updates the value of a characteristic, based on the service
            and characteristic index fields

    @param[in]  charHandle
                The handle of the GattCharacteristic to write to
    @param[in]  buffer
                Data to use when updating the characteristic's value
                (raw byte array in LSB format)
    @param[in]  len
                The number of bytes in buffer

    @returns    ble_error_t

    @retval     BLE_ERROR_NONE
                Everything executed properly

    @section EXAMPLE

    @code

    @endcode
*/
/**************************************************************************/
ble_error_t nRF51GattServer::updateValue(uint16_t charHandle, uint8_t buffer[], uint16_t len, bool localOnly)
{
  uint16_t gapConnectionHandle = nRF51Gap::getInstance().getConnectionHandle();

  if (localOnly)
  {
    /* Only update locally regardless of notify/indicate */
    ASSERT_INT( ERROR_NONE, sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), BLE_ERROR_PARAM_OUT_OF_RANGE );
  }

  if ((p_characteristics[charHandle]->properties & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) &&
      (gapConnectionHandle != BLE_CONN_HANDLE_INVALID) )
  {
    /* HVX update for the characteristic value */
    ble_gatts_hvx_params_t hvx_params;

    hvx_params.handle = nrfCharacteristicHandles[charHandle].value_handle;
    hvx_params.type   = (p_characteristics[charHandle]->properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)  ? BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INDICATION;
    hvx_params.offset = 0;
    hvx_params.p_data = buffer;
    hvx_params.p_len  = &len;

    error_t error = (error_t) sd_ble_gatts_hvx(gapConnectionHandle, &hvx_params);

    /* ERROR_INVALID_STATE, ERROR_BUSY, ERROR_GATTS_SYS_ATTR_MISSING and ERROR_NO_TX_BUFFERS the ATT table has been updated. */
    if ( (error != ERROR_NONE                      ) && (error != ERROR_INVALID_STATE) &&
         (error != ERROR_BLE_NO_TX_BUFFERS         ) && (error != ERROR_BUSY         ) &&
         (error != ERROR_BLEGATTS_SYS_ATTR_MISSING ) )
    {
      ASSERT_INT( ERROR_NONE, sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), BLE_ERROR_PARAM_OUT_OF_RANGE );
    }
  } else
  {
    ASSERT_INT( ERROR_NONE, sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), BLE_ERROR_PARAM_OUT_OF_RANGE );
  }

  return BLE_ERROR_NONE;
}

/**************************************************************************/
/*!
    @brief  Callback handler for events getting pushed up from the SD
*/
/**************************************************************************/
void nRF51GattServer::hwCallback(ble_evt_t * p_ble_evt)
{
  uint16_t handle_value;
  GattServerEvents::gattEvent_t event;

  switch (p_ble_evt->header.evt_id)
  {
    case BLE_GATTS_EVT_WRITE:
      /* There are 2 use case here: Values being updated & CCCD (indicate/notify) enabled */

      /* 1.) Handle CCCD changes */
      handle_value = p_ble_evt->evt.gatts_evt.params.write.handle;
      for(uint8_t i=0; i<characteristicCount; i++)
      {
        if ( (p_characteristics[i]->properties & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) &&
             (nrfCharacteristicHandles[i].cccd_handle == handle_value) )
        {
          uint16_t cccd_value = (p_ble_evt->evt.gatts_evt.params.write.data[1] << 8) | p_ble_evt->evt.gatts_evt.params.write.data[0]; /* Little Endian but M0 may be mis-aligned */

          if ( ((p_characteristics[i]->properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) && (cccd_value & BLE_GATT_HVX_INDICATION  )) ||
               ((p_characteristics[i]->properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY  ) && (cccd_value & BLE_GATT_HVX_NOTIFICATION)))
          {
            event = GattServerEvents::GATT_EVENT_UPDATES_ENABLED;
          } else
          {
            event = GattServerEvents::GATT_EVENT_UPDATES_DISABLED;
          }

          handleEvent(event, i);
          return;
        }
      }

      /* 2.) Changes to the characteristic value will be handled with other events below */
      event = GattServerEvents::GATT_EVENT_DATA_WRITTEN;
      break;

    case BLE_GATTS_EVT_HVC:
      /* Indication confirmation received */
      event        = GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED;
      handle_value = p_ble_evt->evt.gatts_evt.params.hvc.handle;
      break;

    default:
      return;
  }

  /* Find index (charHandle) in the pool */
  for(uint8_t i=0; i<characteristicCount; i++)
  {
    if (nrfCharacteristicHandles[i].value_handle == handle_value)
    {
      handleEvent(event, i);
      break;
    }
  }
}
<commit_msg>Fixed GAP header reference<commit_after>/* mbed Microcontroller Library
 * Copyright (c) 2006-2013 ARM Limited
 *
 * 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.
 */

#include "nRF51GattServer.h"
#include "mbed.h"

#include "common/common.h"
#include "btle/custom/custom_helper.h"

#include "nRF51Gap.h"

/**************************************************************************/
/*!
    @brief  Adds a new service to the GATT table on the peripheral

    @returns    ble_error_t

    @retval     BLE_ERROR_NONE
                Everything executed properly

    @section EXAMPLE

    @code

    @endcode
*/
/**************************************************************************/
ble_error_t nRF51GattServer::addService(GattService & service)
{
    /* ToDo: Make sure we don't overflow the array, etc. */
    /* ToDo: Make sure this service UUID doesn't already exist (?) */
    /* ToDo: Basic validation */

    /* Add the service to the nRF51 */
    ble_uuid_t uuid;

    if (service.primaryServiceID.type == UUID::UUID_TYPE_SHORT)
    {
      /* 16-bit BLE UUID */
      uuid.type = BLE_UUID_TYPE_BLE;
    }
    else
    {
      /* 128-bit Custom UUID */
      uuid.type = custom_add_uuid_base( service.primaryServiceID.base );
    }

    uuid.uuid = service.primaryServiceID.value;

    ASSERT( ERROR_NONE == sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &uuid, &service.handle), BLE_ERROR_PARAM_OUT_OF_RANGE );

    /* Add characteristics to the service */
    for (uint8_t i = 0; i < service.characteristicCount; i++)
    {
      GattCharacteristic * p_char = service.characteristics[i];

      uuid.uuid = p_char->uuid;
      ASSERT ( ERROR_NONE == custom_add_in_characteristic(service.handle, &uuid, p_char->properties,
                                                          NULL, p_char->lenMin, p_char->lenMax, &nrfCharacteristicHandles[characteristicCount]), BLE_ERROR_PARAM_OUT_OF_RANGE );

      /* Update the characteristic handle */
      p_char->handle = characteristicCount;
      p_characteristics[characteristicCount++] = p_char;
    }

    serviceCount++;

    return BLE_ERROR_NONE;
}

/**************************************************************************/
/*!
    @brief  Reads the value of a characteristic, based on the service
            and characteristic index fields

    @param[in]  charHandle
                The handle of the GattCharacteristic to read from
    @param[in]  buffer
                Buffer to hold the the characteristic's value
                (raw byte array in LSB format)
    @param[in]  len
                The number of bytes read into the buffer

    @returns    ble_error_t

    @retval     BLE_ERROR_NONE
                Everything executed properly

    @section EXAMPLE

    @code

    @endcode
*/
/**************************************************************************/
ble_error_t nRF51GattServer::readValue(uint16_t charHandle, uint8_t buffer[], uint16_t len)
{
    ASSERT( ERROR_NONE == sd_ble_gatts_value_get(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), BLE_ERROR_PARAM_OUT_OF_RANGE);

    return BLE_ERROR_NONE;
}

/**************************************************************************/
/*!
    @brief  Updates the value of a characteristic, based on the service
            and characteristic index fields

    @param[in]  charHandle
                The handle of the GattCharacteristic to write to
    @param[in]  buffer
                Data to use when updating the characteristic's value
                (raw byte array in LSB format)
    @param[in]  len
                The number of bytes in buffer

    @returns    ble_error_t

    @retval     BLE_ERROR_NONE
                Everything executed properly

    @section EXAMPLE

    @code

    @endcode
*/
/**************************************************************************/
ble_error_t nRF51GattServer::updateValue(uint16_t charHandle, uint8_t buffer[], uint16_t len, bool localOnly)
{
  uint16_t gapConnectionHandle = nRF51Gap::getInstance().getConnectionHandle();

  if (localOnly)
  {
    /* Only update locally regardless of notify/indicate */
    ASSERT_INT( ERROR_NONE, sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), BLE_ERROR_PARAM_OUT_OF_RANGE );
  }

  if ((p_characteristics[charHandle]->properties & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) &&
      (gapConnectionHandle != BLE_CONN_HANDLE_INVALID) )
  {
    /* HVX update for the characteristic value */
    ble_gatts_hvx_params_t hvx_params;

    hvx_params.handle = nrfCharacteristicHandles[charHandle].value_handle;
    hvx_params.type   = (p_characteristics[charHandle]->properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)  ? BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INDICATION;
    hvx_params.offset = 0;
    hvx_params.p_data = buffer;
    hvx_params.p_len  = &len;

    error_t error = (error_t) sd_ble_gatts_hvx(gapConnectionHandle, &hvx_params);

    /* ERROR_INVALID_STATE, ERROR_BUSY, ERROR_GATTS_SYS_ATTR_MISSING and ERROR_NO_TX_BUFFERS the ATT table has been updated. */
    if ( (error != ERROR_NONE                      ) && (error != ERROR_INVALID_STATE) &&
         (error != ERROR_BLE_NO_TX_BUFFERS         ) && (error != ERROR_BUSY         ) &&
         (error != ERROR_BLEGATTS_SYS_ATTR_MISSING ) )
    {
      ASSERT_INT( ERROR_NONE, sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), BLE_ERROR_PARAM_OUT_OF_RANGE );
    }
  } else
  {
    ASSERT_INT( ERROR_NONE, sd_ble_gatts_value_set(nrfCharacteristicHandles[charHandle].value_handle, 0, &len, buffer), BLE_ERROR_PARAM_OUT_OF_RANGE );
  }

  return BLE_ERROR_NONE;
}

/**************************************************************************/
/*!
    @brief  Callback handler for events getting pushed up from the SD
*/
/**************************************************************************/
void nRF51GattServer::hwCallback(ble_evt_t * p_ble_evt)
{
  uint16_t handle_value;
  GattServerEvents::gattEvent_t event;

  switch (p_ble_evt->header.evt_id)
  {
    case BLE_GATTS_EVT_WRITE:
      /* There are 2 use case here: Values being updated & CCCD (indicate/notify) enabled */

      /* 1.) Handle CCCD changes */
      handle_value = p_ble_evt->evt.gatts_evt.params.write.handle;
      for(uint8_t i=0; i<characteristicCount; i++)
      {
        if ( (p_characteristics[i]->properties & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) &&
             (nrfCharacteristicHandles[i].cccd_handle == handle_value) )
        {
          uint16_t cccd_value = (p_ble_evt->evt.gatts_evt.params.write.data[1] << 8) | p_ble_evt->evt.gatts_evt.params.write.data[0]; /* Little Endian but M0 may be mis-aligned */

          if ( ((p_characteristics[i]->properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) && (cccd_value & BLE_GATT_HVX_INDICATION  )) ||
               ((p_characteristics[i]->properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY  ) && (cccd_value & BLE_GATT_HVX_NOTIFICATION)))
          {
            event = GattServerEvents::GATT_EVENT_UPDATES_ENABLED;
          } else
          {
            event = GattServerEvents::GATT_EVENT_UPDATES_DISABLED;
          }

          handleEvent(event, i);
          return;
        }
      }

      /* 2.) Changes to the characteristic value will be handled with other events below */
      event = GattServerEvents::GATT_EVENT_DATA_WRITTEN;
      break;

    case BLE_GATTS_EVT_HVC:
      /* Indication confirmation received */
      event        = GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED;
      handle_value = p_ble_evt->evt.gatts_evt.params.hvc.handle;
      break;

    default:
      return;
  }

  /* Find index (charHandle) in the pool */
  for(uint8_t i=0; i<characteristicCount; i++)
  {
    if (nrfCharacteristicHandles[i].value_handle == handle_value)
    {
      handleEvent(event, i);
      break;
    }
  }
}
<|endoftext|>


<commit_before>// Copyright 2004-present Facebook. All Rights Reserved.

#include <string>
#include <fstream>
#include <streambuf>
#include <sstream>
#include <map>

#include <stdlib.h>
#include <unistd.h>
#include <proc/readproc.h>

#include <osquery/core.h>
#include <osquery/tables.h>
#include <osquery/filesystem.h>

namespace osquery {
namespace tables {

#ifdef PROC_EDITCMDLCVT
/// EDITCMDLCVT is available in libprocps3-dev
#define PROC_SELECTS                                                 \
  PROC_FILLCOM | PROC_EDITCMDLCVT | PROC_FILLMEM | PROC_FILLSTATUS | \
      PROC_FILLSTAT
#else
#define PROC_SELECTS \
  PROC_FILLCOM | PROC_FILLMEM | PROC_FILLSTATUS | PROC_FILLSTAT
#endif

std::string proc_name(const proc_t* proc_info) {
  char cmd[17]; // cmd is a 16 char buffer

  memset(cmd, 0, 17);
  memcpy(cmd, proc_info->cmd, 16);
  return std::string(cmd);
}

std::string proc_attr(const std::string& attr, const proc_t* proc_info) {
  std::stringstream filename;

  filename << "/proc/" << proc_info->tid << "/" << attr;
  return filename.str();
}

std::string proc_cmdline(const proc_t* proc_info) {
  std::string attr;
  std::string result;

  attr = proc_attr("cmdline", proc_info);
  std::ifstream fd(attr, std::ios::in | std::ios::binary);
  if (fd) {
    result = std::string(std::istreambuf_iterator<char>(fd),
                         std::istreambuf_iterator<char>());
  }

  return result;
}

std::string proc_link(const proc_t* proc_info) {
  std::string attr;
  std::string result;
  char* link_path;
  long path_max;
  int bytes;

  // The exe is a symlink to the binary on-disk.
  attr = proc_attr("exe", proc_info);
  path_max = pathconf(attr.c_str(), _PC_PATH_MAX);
  link_path = (char*)malloc(path_max);

  memset(link_path, 0, path_max);
  bytes = readlink(attr.c_str(), link_path, path_max);
  if (bytes >= 0) {
    result = std::string(link_path);
  }

  free(link_path);
  return result;
}

std::map<std::string, std::string> proc_env(const proc_t* proc_info) {
  std::map<std::string, std::string> env;
  std::string attr = proc_attr("environ", proc_info);
  std::string buf;

  std::ifstream fd(attr, std::ios::in | std::ios::binary);

  while (!(fd.fail() || fd.eof())) {
    std::getline(fd, buf, '\0');
    size_t idx = buf.find_first_of("=");

    std::string key = buf.substr(0, idx);
    std::string value = buf.substr(idx + 1);

    env[key] = value;
  }
  return env;
}

/**
 * @brief deallocate the space allocated by readproc if the passed rbuf was NULL
 *
 * @param p The rbuf to free
 */
void standard_freeproc(proc_t* p) {
  if (!p) { // in case p is NULL
    return;
  }

#ifdef PROC_EDITCMDLCVT
  freeproc(p);
  return;
#endif

  // ptrs are after strings to avoid copying memory when building them.
  // so free is called on the address of the address of strvec[0].
  if (p->cmdline) {
    free((void*)*p->cmdline);
  }
  if (p->environ) {
    free((void*)*p->environ);
  }
  free(p);
}

QueryData genProcesses(QueryContext& context) {
  QueryData results;

  proc_t* proc_info;
  PROCTAB* proc = openproc(PROC_SELECTS);

  // Populate proc struc for each process.
  while ((proc_info = readproc(proc, NULL))) {
    Row r;

    r["pid"] = INTEGER(proc_info->tid);
    r["uid"] = BIGINT((unsigned int)proc_info->ruid);
    r["gid"] = BIGINT((unsigned int)proc_info->rgid);
    r["euid"] = BIGINT((unsigned int)proc_info->euid);
    r["egid"] = BIGINT((unsigned int)proc_info->egid);
    r["name"] = proc_name(proc_info);
    r["cmdline"] = proc_cmdline(proc_info);
    r["path"] = proc_link(proc_info);
    r["on_disk"] = osquery::pathExists(r["path"]).toString();

    r["resident_size"] = INTEGER(proc_info->vm_rss);
    r["phys_footprint"] = INTEGER(proc_info->vm_size);
    r["user_time"] = INTEGER(proc_info->utime);
    r["system_time"] = INTEGER(proc_info->stime);
    r["start_time"] = INTEGER(proc_info->start_time);
    r["parent"] = INTEGER(proc_info->ppid);

    results.push_back(r);
    standard_freeproc(proc_info);
  }

  closeproc(proc);

  return results;
}

QueryData genProcessEnvs(QueryContext& context) {
  QueryData results;

  proc_t* proc_info;
  PROCTAB* proc = openproc(PROC_SELECTS);

  // Populate proc struc for each process.

  while ((proc_info = readproc(proc, NULL))) {
    auto env = proc_env(proc_info);
    for (auto itr = env.begin(); itr != env.end(); ++itr) {
      Row r;
      r["pid"] = INTEGER(proc_info->tid);
      r["name"] = proc_name(proc_info);
      r["path"] = proc_link(proc_info);
      r["key"] = itr->first;
      r["value"] = itr->second;
      results.push_back(r);
    }

    standard_freeproc(proc_info);
  }

  closeproc(proc);

  return results;
}

QueryData genProcessOpenFiles(QueryContext& context) {
  QueryData results;
  return results;
}
}
}
<commit_msg>Replace linux cmdline tokens with spaces<commit_after>// Copyright 2004-present Facebook. All Rights Reserved.

#include <string>
#include <fstream>
#include <map>

#include <stdlib.h>
#include <unistd.h>
#include <proc/readproc.h>

#include <osquery/core.h>
#include <osquery/tables.h>
#include <osquery/filesystem.h>

namespace osquery {
namespace tables {

#ifdef PROC_EDITCMDLCVT
/// EDITCMDLCVT is available in libprocps3-dev
#define PROC_SELECTS                                                 \
  PROC_FILLCOM | PROC_EDITCMDLCVT | PROC_FILLMEM | PROC_FILLSTATUS | \
      PROC_FILLSTAT
#else
#define PROC_SELECTS \
  PROC_FILLCOM | PROC_FILLMEM | PROC_FILLSTATUS | PROC_FILLSTAT
#endif

std::string proc_name(const proc_t* proc_info) {
  char cmd[17]; // cmd is a 16 char buffer

  memset(cmd, 0, 17);
  memcpy(cmd, proc_info->cmd, 16);
  return std::string(cmd);
}

std::string proc_attr(const std::string& attr, const proc_t* proc_info) {
  std::stringstream filename;

  filename << "/proc/" << proc_info->tid << "/" << attr;
  return filename.str();
}

std::string proc_cmdline(const proc_t* proc_info) {
  std::string attr;
  std::string result;

  attr = proc_attr("cmdline", proc_info);
  std::ifstream fd(attr, std::ios::in | std::ios::binary);
  if (fd) {
    result = std::string(std::istreambuf_iterator<char>(fd),
                         std::istreambuf_iterator<char>());
    std::replace_if(
      result.begin(),
      result.end(),
      [](const char& c) { return c == 0; },
      ' ');
  }

  return result;
}

std::string proc_link(const proc_t* proc_info) {
  std::string attr;
  std::string result;
  char* link_path;
  long path_max;
  int bytes;

  // The exe is a symlink to the binary on-disk.
  attr = proc_attr("exe", proc_info);
  path_max = pathconf(attr.c_str(), _PC_PATH_MAX);
  link_path = (char*)malloc(path_max);

  memset(link_path, 0, path_max);
  bytes = readlink(attr.c_str(), link_path, path_max);
  if (bytes >= 0) {
    result = std::string(link_path);
  }

  free(link_path);
  return result;
}

std::map<std::string, std::string> proc_env(const proc_t* proc_info) {
  std::map<std::string, std::string> env;
  std::string attr = proc_attr("environ", proc_info);
  std::string buf;

  std::ifstream fd(attr, std::ios::in | std::ios::binary);

  while (!(fd.fail() || fd.eof())) {
    std::getline(fd, buf, '\0');
    size_t idx = buf.find_first_of("=");

    std::string key = buf.substr(0, idx);
    std::string value = buf.substr(idx + 1);

    env[key] = value;
  }
  return env;
}

/**
 * @brief deallocate the space allocated by readproc if the passed rbuf was NULL
 *
 * @param p The rbuf to free
 */
void standard_freeproc(proc_t* p) {
  if (!p) { // in case p is NULL
    return;
  }

#ifdef PROC_EDITCMDLCVT
  freeproc(p);
  return;
#endif

  // ptrs are after strings to avoid copying memory when building them.
  // so free is called on the address of the address of strvec[0].
  if (p->cmdline) {
    free((void*)*p->cmdline);
  }
  if (p->environ) {
    free((void*)*p->environ);
  }
  free(p);
}

QueryData genProcesses(QueryContext& context) {
  QueryData results;

  proc_t* proc_info;
  PROCTAB* proc = openproc(PROC_SELECTS);

  // Populate proc struc for each process.
  while ((proc_info = readproc(proc, NULL))) {
    Row r;

    r["pid"] = INTEGER(proc_info->tid);
    r["uid"] = BIGINT((unsigned int)proc_info->ruid);
    r["gid"] = BIGINT((unsigned int)proc_info->rgid);
    r["euid"] = BIGINT((unsigned int)proc_info->euid);
    r["egid"] = BIGINT((unsigned int)proc_info->egid);
    r["name"] = proc_name(proc_info);
    r["cmdline"] = proc_cmdline(proc_info);
    r["path"] = proc_link(proc_info);
    r["on_disk"] = osquery::pathExists(r["path"]).toString();

    r["resident_size"] = INTEGER(proc_info->vm_rss);
    r["phys_footprint"] = INTEGER(proc_info->vm_size);
    r["user_time"] = INTEGER(proc_info->utime);
    r["system_time"] = INTEGER(proc_info->stime);
    r["start_time"] = INTEGER(proc_info->start_time);
    r["parent"] = INTEGER(proc_info->ppid);

    results.push_back(r);
    standard_freeproc(proc_info);
  }

  closeproc(proc);

  return results;
}

QueryData genProcessEnvs(QueryContext& context) {
  QueryData results;

  proc_t* proc_info;
  PROCTAB* proc = openproc(PROC_SELECTS);

  // Populate proc struc for each process.

  while ((proc_info = readproc(proc, NULL))) {
    auto env = proc_env(proc_info);
    for (auto itr = env.begin(); itr != env.end(); ++itr) {
      Row r;
      r["pid"] = INTEGER(proc_info->tid);
      r["name"] = proc_name(proc_info);
      r["path"] = proc_link(proc_info);
      r["key"] = itr->first;
      r["value"] = itr->second;
      results.push_back(r);
    }

    standard_freeproc(proc_info);
  }

  closeproc(proc);

  return results;
}

QueryData genProcessOpenFiles(QueryContext& context) {
  QueryData results;
  return results;
}
}
}
<|endoftext|>


<commit_before>#include "evaluator.hpp"

using namespace std;

constexpr unsigned square_to_piece(char square) { return 1 << (square - 1); }
constexpr char piece_to_square(unsigned piece) {
  return 32 - __builtin_clz(piece);
}

namespace eval {
/*
 * For every function in this file, there should be a corresponding
 * 'REGISTER_ENUM(<func_name>)' entry in evaluator_names.hpp
 *
 * All functions in this file must have the signature:
 * int eval_<descriptive_name>(const array<unsigned, 4>, char, int)
 *
 * They must also be within namespace eval{}
 */

int eval_black_dyke(const array<unsigned, 4> &pieces, char, int weight) {
  int retval = __builtin_popcount(pieces[0] & 0x4223);
  retval *= retval * weight;
  retval /= 25;
  return retval;
}

int eval_white_dyke(const array<unsigned, 4> &pieces, char, int weight) {
  int retval = __builtin_popcount(pieces[1] & 0xc4420000u);
  retval *= retval * -weight;
  retval /= 25;
  return retval;
}

int eval_d_diagonal(const array<unsigned, 4> &pieces, char, int weight) {
  int black = __builtin_popcount(pieces[0] & 0x11224488);
  black *= black * weight;
  black /= 64;

  int white = __builtin_popcount(pieces[0] & 0x11224488);
  white *= white * weight;
  white /= 64;

  return black - white;
}

int eval_black_pyramid(const array<unsigned, 4> &pieces, char, int weight) {
  int retval = __builtin_popcount(pieces[0] & 0x267);
  retval *= retval * weight;
  retval /= 36;
  return retval;
}

int eval_white_pyramid(const array<unsigned, 4> &pieces, char, int weight) {
  int retval = __builtin_popcount(pieces[1] & 0xe6400000u);
  retval *= retval * -weight;
  retval /= 36;
  return retval;
}

int eval_centralized_kings(const array<unsigned, 4> &pieces,
                           char player __attribute((unused)), int weight) {
  int retval = __builtin_popcount(pieces[2] & 0x00666600u);
  retval -= __builtin_popcount(pieces[3] & 0x00666600u);
  return weight * retval;
}

int eval_trapped_kings(const array<unsigned, 4> &pieces, char player, int) {
  return 0;

  int retval = 0;
  if (player) {                        // white to play
    for (unsigned a = pieces[2]; a;) { // search for trapped black kings
      const unsigned piece = 0x80000000u >> __builtin_clz(a);

      a ^= piece;
    }
    for (unsigned a = pieces[3]; a;) { // search for trapped white kings
      const unsigned piece = 0x80000000u >> __builtin_clz(a);

      a ^= piece;
    }
  } else {                             // black to play
    for (unsigned a = pieces[2]; a;) { // search for trapped black kings
      const unsigned piece = 0x80000000u >> __builtin_clz(a);

      a ^= piece;
    }
    for (unsigned a = pieces[3]; a;) { // search for trapped white kings
      const unsigned piece = 0x80000000u >> __builtin_clz(a);

      a ^= piece;
    }
  }
  return retval;
}
}
<commit_msg>I did the long dyke formation wrong.<commit_after>#include "evaluator.hpp"

using namespace std;

constexpr unsigned square_to_piece(char square) { return 1 << (square - 1); }
constexpr char piece_to_square(unsigned piece) {
  return 32 - __builtin_clz(piece);
}

namespace eval {
/*
 * For every function in this file, there should be a corresponding
 * 'REGISTER_ENUM(<func_name>)' entry in evaluator_names.hpp
 *
 * All functions in this file must have the signature:
 * int eval_<descriptive_name>(const array<unsigned, 4>, char, int)
 *
 * They must also be within namespace eval{}
 */

int eval_black_dyke(const array<unsigned, 4> &pieces, char, int weight) {
  int retval = __builtin_popcount(pieces[0] & 0x44223);
  retval *= retval * weight;
  retval /= 36;
  return retval;
}

int eval_white_dyke(const array<unsigned, 4> &pieces, char, int weight) {
  int retval = __builtin_popcount(pieces[1] & 0xc4422000u);
  retval *= retval * -weight;
  retval /= 36;
  return retval;
}

int eval_d_diagonal(const array<unsigned, 4> &pieces, char, int weight) {
  int black = __builtin_popcount(pieces[0] & 0x11224488);
  black *= black * weight;
  black /= 64;

  int white = __builtin_popcount(pieces[0] & 0x11224488);
  white *= white * weight;
  white /= 64;

  return black - white;
}

int eval_black_pyramid(const array<unsigned, 4> &pieces, char, int weight) {
  int retval = __builtin_popcount(pieces[0] & 0x267);
  retval *= retval * weight;
  retval /= 36;
  return retval;
}

int eval_white_pyramid(const array<unsigned, 4> &pieces, char, int weight) {
  int retval = __builtin_popcount(pieces[1] & 0xe6400000u);
  retval *= retval * -weight;
  retval /= 36;
  return retval;
}

int eval_centralized_kings(const array<unsigned, 4> &pieces,
                           char player __attribute((unused)), int weight) {
  int retval = __builtin_popcount(pieces[2] & 0x00666600u);
  retval -= __builtin_popcount(pieces[3] & 0x00666600u);
  return weight * retval;
}

int eval_trapped_kings(const array<unsigned, 4> &pieces, char player, int) {
  return 0;

  int retval = 0;
  if (player) {                        // white to play
    for (unsigned a = pieces[2]; a;) { // search for trapped black kings
      const unsigned piece = 0x80000000u >> __builtin_clz(a);

      a ^= piece;
    }
    for (unsigned a = pieces[3]; a;) { // search for trapped white kings
      const unsigned piece = 0x80000000u >> __builtin_clz(a);

      a ^= piece;
    }
  } else {                             // black to play
    for (unsigned a = pieces[2]; a;) { // search for trapped black kings
      const unsigned piece = 0x80000000u >> __builtin_clz(a);

      a ^= piece;
    }
    for (unsigned a = pieces[3]; a;) { // search for trapped white kings
      const unsigned piece = 0x80000000u >> __builtin_clz(a);

      a ^= piece;
    }
  }
  return retval;
}
}
<|endoftext|>


<commit_before>#pragma once

#include <array>
#include <functional>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"

#define REGISTER_ENUM(x) x,
enum eval_names {
#include "evaluator_names.hpp"
  eval_count
};
#undef REGISTER_ENUM

#define REGISTER_ENUM(x) #x,
static const char *eval_names_text[] = {
#include "evaluator_names.hpp"
    "invalid"};
#undef REGISTER_ENUM

namespace eval {
#define REGISTER_ENUM(x) int x(const std::array<unsigned, 4> &, char, int);
#include "evaluator_names.hpp"
#undef REGISTER_ENUM
}

#define REGISTER_ENUM(x) &eval::x,
static const std::function<int(const std::array<unsigned, 4> &, char, int)>
    eval_funcs[]{
#include "evaluator_names.hpp"
        NULL};
#undef REGISTER_ENUM

#pragma GCC diagnostic pop
<commit_msg>Using std::array<> in evaluator.hpp instead of C arrays.<commit_after>#pragma once

#include <array>
#include <functional>
#include <string>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"

#define REGISTER_ENUM(x) x,
enum eval_names {
#include "evaluator_names.hpp"
  eval_count
};
#undef REGISTER_ENUM

#define REGISTER_ENUM(x) #x,
static const std::array<std::string, eval_names::eval_count + 1>
    eval_names_text{
#include "evaluator_names.hpp"
        "invalid"};
#undef REGISTER_ENUM

namespace eval {
#define REGISTER_ENUM(x) int x(const std::array<unsigned, 4> &, char, int);
#include "evaluator_names.hpp"
#undef REGISTER_ENUM
}

#define REGISTER_ENUM(x) &eval::x,
static const std::array<
    std::function<int(const std::array<unsigned, 4> &, char, int)>,
    eval_names::eval_count + 1>
    eval_funcs{
#include "evaluator_names.hpp"
        NULL};
#undef REGISTER_ENUM

#pragma GCC diagnostic pop
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "SocketServer.h"

SocketServer::SocketServer(void)
{
	ListenSocket = INVALID_SOCKET;
	ClientSocket = INVALID_SOCKET;
	recvbuflen = DEFAULT_BUFLEN;
}

void SocketServer::Start(void)
{
	// Initialize Winsock
	iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (iResult != 0) {
		printf("WSAStartup failed with error: %d\n", iResult);
		return;
	}

	ZeroMemory(&hints, sizeof(hints));
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;
	hints.ai_flags = AI_PASSIVE;

	// Resolve the server address and port
	iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
	if (iResult != 0) {
		printf("getaddrinfo failed with error: %d\n", iResult);
		WSACleanup();
		return;
	}

	// Create a SOCKET for connecting to server
	ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
	if (ListenSocket == INVALID_SOCKET) {
		printf("socket failed with error: %ld\n", WSAGetLastError());
		freeaddrinfo(result);
		WSACleanup();
		return;
	}

	// Setup the TCP listening socket
	iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
	if (iResult == SOCKET_ERROR) {
		printf("bind failed with error: %d\n", WSAGetLastError());
		freeaddrinfo(result);
		closesocket(ListenSocket);
		WSACleanup();
		return;
	}

	freeaddrinfo(result);

	iResult = listen(ListenSocket, SOMAXCONN);
	if (iResult == SOCKET_ERROR) {
		printf("listen failed with error: %d\n", WSAGetLastError());
		closesocket(ListenSocket);
		WSACleanup();
		return;
	}

	//SetConsoleCtrlHandler(HandlerRoutine, TRUE);

	// Accept a client socket
	do
	{
		printf("listening...\n");
		ClientSocket = accept(ListenSocket, NULL, NULL);
		if (ClientSocket == INVALID_SOCKET) {
			printf("accept failed with error: %d\n", WSAGetLastError());
			closesocket(ListenSocket);
			WSACleanup();
			return;
		}
		printf("ClientSocket...%d\n", ClientSocket);
		SocketdThread* socketdThread = SocketdThread::Create(ClientSocket);
		auto w = socketdThread->Wait(100);
		//auto t = socketdThread->Terminate(1);
		delete socketdThread;
	} while (true);

}

SocketServer::~SocketServer(void)
{
	printf("ClientSocket returned\n");
	// No longer need server socket
	closesocket(ListenSocket);
	closesocket(ClientSocket);
	WSACleanup();
}
<commit_msg>Delete SocketServer.cpp<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (c) 2012-2013 Stanford University
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>

#include <unistd.h>
#include <sys/param.h>
#include <sys/types.h>

#include <string>
#include <iostream>

using namespace std;

#include <ori/version.h>
#include <oriutil/debug.h>
#include <ori/repo.h>
#include <ori/udsclient.h>
#include <ori/udsrepo.h>
#include <ori/server.h>

#include "fuse_cmd.h"

UDSClient *client;
UDSRepo repository;

/********************************************************************
 *
 *
 * Command Infrastructure
 *
 *
 ********************************************************************/

#define CMD_NEED_FUSE           1
#define CMD_DEBUG               2

typedef struct Cmd {
    const char *name;
    const char *desc;
    int (*cmd)(int argc, char * const argv[]);
    void (*usage)(void);
    int flags;
} Cmd;

// General Operations
int cmd_addkey(int argc, char * const argv[]);
int cmd_branches(int argc, char * const argv[]);
int cmd_branch(int argc, char * const argv[]);
int cmd_checkout(int argc, char * const argv[]);
void usage_cleanup();
int cmd_cleanup(int argc, char * const argv[]);
int cmd_diff(int argc, char * const argv[]);
int cmd_filelog(int argc, char * const argv[]);
int cmd_findheads(int argc, char * const argv[]);
int cmd_gc(int argc, char * const argv[]);
void usage_graft(void);
int cmd_graft(int argc, char * const argv[]);
void usage_list();
int cmd_list(int argc, char * const argv[]);
int cmd_listkeys(int argc, char * const argv[]);
int cmd_log(int argc, char * const argv[]);
int cmd_merge(int argc, char * const argv[]);
void usage_newfs();
int cmd_newfs(int argc, char * const argv[]);
int cmd_pull(int argc, char * const argv[]);
int cmd_rebuildindex(int argc, char * const argv[]);
int cmd_rebuildrefs(int argc, char * const argv[]);
int cmd_remote(int argc, char * const argv[]);
void usage_removefs();
int cmd_removefs(int argc, char * const argv[]);
int cmd_removekey(int argc, char * const argv[]);
void usage_replicate(void);
int cmd_replicate(int argc, char * const argv[]);
int cmd_setkey(int argc, char * const argv[]);
int cmd_show(int argc, char * const argv[]);
void usage_snapshot(void);
int cmd_snapshot(int argc, char * const argv[]);
int cmd_snapshots(int argc, char * const argv[]);
int cmd_status(int argc, char * const argv[]);
int cmd_tip(int argc, char * const argv[]);
int cmd_varlink(int argc, char * const argv[]);

// Debug Operations
int cmd_fsck(int argc, char * const argv[]);
int cmd_purgesnapshot(int argc, char * const argv[]);
int cmd_sshserver(int argc, char * const argv[]); // Internal
static int cmd_help(int argc, char * const argv[]);
static int cmd_version(int argc, char * const argv[]);

static Cmd commands[] = {
    {
        "addkey",
        "Add a trusted public key to the repository (NS)",
        cmd_addkey,
        NULL,
        CMD_DEBUG,
    },
    {
        "branch",
        "Set or print current branch (EXPERIMENTAL) (NS)",
        cmd_branch,
        NULL,
        CMD_DEBUG,
    },
    {
        "branches",
        "List all available branches (EXPERIMENTAL) (NS)",
        cmd_branches,
        NULL,
        CMD_DEBUG,
    },
    {
        "checkout",
        "Checkout a revision of the repository (DEBUG)",
        cmd_checkout,
        NULL,
        CMD_DEBUG | CMD_NEED_FUSE,
    },
    {
        "cleanup",
        "Cleanup a repository after a FUSE crash (DEBUG)",
        cmd_cleanup,
        usage_cleanup,
        CMD_DEBUG,
    },
    {
        "diff",
        "Display a diff of the pending changes (NS)",
        cmd_diff,
        NULL,
        CMD_DEBUG,
    },
    {
        "filelog",
        "Display a log of change to the specified file (NS)",
        cmd_filelog,
        NULL,
        CMD_DEBUG,
    },
    {
        "findheads",
        "Find lost heads (NS)",
        cmd_findheads,
        NULL,
        CMD_DEBUG,
    },
    {
        "gc",
        "Reclaim unused space (NS)",
        cmd_gc,
        NULL,
        CMD_DEBUG,
    },
    {
        "graft",
        "Graft a subtree from a repository into the local repository (NS)",
        cmd_graft,
        usage_graft,
        CMD_DEBUG, /* 0 to allow aliasing of 'cp' */
    },
    {
        "help",
        "Show help for a given topic",
        cmd_help,
        NULL,
        0,
    },
    {
        "list",
        "List local file systems",
        cmd_list,
        usage_list,
        0,
    },
    {
        "listkeys",
        "Display a list of trusted public keys (NS)",
        cmd_listkeys,
        NULL,
        CMD_DEBUG,
    },
    {
        "log",
        "Display a log of commits to the repository",
        cmd_log,
        NULL,
        CMD_NEED_FUSE,
    },
    {
        "merge",
        "Merge two heads",
        cmd_merge,
        NULL,
        CMD_NEED_FUSE,
    },
    {
        "newfs",
        "Create a new file system",
        cmd_newfs,
        usage_newfs,
        0,
    },
    {
        "pull",
        "Pull changes from a repository",
        cmd_pull,
        NULL,
        CMD_NEED_FUSE,
    },
    {
        "purgesnapshot",
        "Purge snapshot (NS)",
        cmd_purgesnapshot,
        NULL,
        CMD_DEBUG,
    },
    {
        "remote",
        "Remote connection management",
        cmd_remote,
        NULL,
        CMD_NEED_FUSE,
    },
    {
        "removefs",
        "Remove a local replica",
        cmd_removefs,
        usage_removefs,
        0,
    },
    {
        "removekey",
        "Remove a public key from the repository (NS)",
        cmd_removekey,
        NULL,
        CMD_DEBUG,
    },
    {
        "replicate",
        "Create a local replica",
        cmd_replicate,
        usage_replicate,
        0,
    },
    {
        "setkey",
        "Set the repository private key for signing commits (NS)",
        cmd_setkey,
        NULL,
        CMD_DEBUG,
    },
    {
        "show",
        "Show repository information",
        cmd_show,
        NULL,
        CMD_NEED_FUSE,
    },
    {
        "snapshot",
        "Create a repository snapshot",
        cmd_snapshot,
        usage_snapshot,
        CMD_NEED_FUSE,
    },
    {
        "snapshots",
        "List all snapshots available in the repository",
        cmd_snapshots,
        NULL,
        CMD_NEED_FUSE,
    },
    {
        "status",
        "Scan for changes since last commit",
        cmd_status,
        NULL,
        CMD_NEED_FUSE,
    },
    {
        "tip",
        "Print the latest commit on this branch",
        cmd_tip,
        NULL,
        CMD_NEED_FUSE,
    },
    {
        "varlink",
        "Get, set, list varlink variables",
        cmd_varlink,
        NULL,
        CMD_NEED_FUSE,
    },
    /* Internal (always hidden) */
    {
        "sshserver",
        NULL, // "Run a simple stdin/out server, intended for SSH access",
        cmd_sshserver,
        NULL,
        0,
    },
    /* Debugging */
    {
        "fsck",
        "Check internal state of FUSE file system (DEBUG)",
        cmd_fsck,
        NULL,
        CMD_NEED_FUSE | CMD_DEBUG,
    },
    {
        "version",
        "Show version information",
        cmd_version,
        NULL,
        CMD_DEBUG,
    },
    { NULL, NULL, NULL, NULL }
};

static int
lookupcmd(const char *cmd)
{
    int i;

    for (i = 0; commands[i].name != NULL; i++)
    {
        if (strcmp(commands[i].name, cmd) == 0)
            return i;
    }

    return -1;
}

static int
cmd_help(int argc, char * const argv[])
{
    int i = 0;

    if (argc >= 2) {
        i = lookupcmd(argv[1]);
        if (i != -1 && commands[i].usage != NULL) {
            commands[i].usage();
            return 0;
        }
        if (i == -1) {
            printf("Unknown command '%s'\n", argv[1]);
        } else {
            printf("No help for command '%s'\n", argv[1]);
        }
        return 0;
    }

    printf("Ori Distributed Personal File System (%s) - Command Line Interface\n\n",
            ORI_VERSION_STR);
    printf("Available commands:\n");
    for (i = 0; commands[i].name != NULL; i++)
    {
#ifndef DEBUG
        if (commands[i].flags & CMD_DEBUG)
            continue;
#endif /* DEBUG */
        if (commands[i].desc != NULL)
            printf("%-15s %s\n", commands[i].name, commands[i].desc);
    }

    printf("\nPlease report bugs to orifs-devel@stanford.edu\n");
    printf("Website: http://ori.scs.stanford.edu/\n");

    return 0;
}

static int
cmd_version(int argc, char * const argv[])
{
    printf("Ori Distributed Personal File System (%s) - Command Line Interface\n",
            ORI_VERSION_STR);
#ifdef GIT_VERSION
    printf("Git Commit Id: " GIT_VERSION "\n");
#endif
#if defined(DEBUG) || defined(ORI_DEBUG)
    printf("Build: DEBUG\n");
#elif defined(ORI_PERF)
    printf("Build: PERF\n");
#else
    printf("Build: RELEASE\n");
#endif

    return 0;
}

int
main(int argc, char *argv[])
{
    int idx;

    if (argc == 1) {
        return cmd_help(0, NULL);
    }

    idx = lookupcmd(argv[1]);
    if (idx == -1) {
        printf("Unknown command '%s'\n", argv[1]);
        cmd_help(0, NULL);
        return 1;
    }

#if defined(DEBUG) || defined(ORI_PERF)
    string logPath = Util_GetHome() + "/.ori/oricli.log";
    ori_open_log(logPath);
#endif

    client = NULL;
    if (commands[idx].flags & CMD_NEED_FUSE) {
        string repoPath;

        if (!OF_HasFuse()) {
            printf("This command must be run on a mounted file system!\n");
            exit(1);
        }

        repoPath = OF_RepoPath();
        if (repoPath == "") {
            printf("Cannot find repository path!\n");
            exit(1);
        }

        try {
            client = new UDSClient(repoPath);
            if (client->connect() < 0) {
                printf("Failed to connect to UDS Repository!\n");
                exit(1);
            }

            repository = UDSRepo(client);
        } catch (exception &e) {
            printf("Failed to connect to FUSE: %s\n", e.what());
            exit(1);
        }
    }

    DLOG("Executing '%s'", argv[1]);
    int status = commands[idx].cmd(argc-1, (char * const*)argv+1);

    if (client)
        delete client;

    return status;
}

<commit_msg>Cleanup CLI interface<commit_after>/*
 * Copyright (c) 2012-2013 Stanford University
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>

#include <unistd.h>
#include <sys/param.h>
#include <sys/types.h>

#include <string>
#include <iostream>

using namespace std;

#include <ori/version.h>
#include <oriutil/debug.h>
#include <ori/repo.h>
#include <ori/udsclient.h>
#include <ori/udsrepo.h>
#include <ori/server.h>

#include "fuse_cmd.h"

UDSClient *client;
UDSRepo repository;

/********************************************************************
 *
 *
 * Command Infrastructure
 *
 *
 ********************************************************************/

#define CMD_NEED_FUSE           1
#define CMD_DEBUG               2
#define CMD_EXPERIMENTAL        4

typedef struct Cmd {
    const char *name;
    const char *desc;
    int (*cmd)(int argc, char * const argv[]);
    void (*usage)(void);
    int flags;
} Cmd;

// General Operations
int cmd_addkey(int argc, char * const argv[]);
int cmd_branches(int argc, char * const argv[]);
int cmd_branch(int argc, char * const argv[]);
int cmd_checkout(int argc, char * const argv[]);
void usage_cleanup();
int cmd_cleanup(int argc, char * const argv[]);
int cmd_diff(int argc, char * const argv[]);
int cmd_filelog(int argc, char * const argv[]);
int cmd_findheads(int argc, char * const argv[]);
int cmd_gc(int argc, char * const argv[]);
void usage_graft(void);
int cmd_graft(int argc, char * const argv[]);
void usage_list();
int cmd_list(int argc, char * const argv[]);
int cmd_listkeys(int argc, char * const argv[]);
int cmd_log(int argc, char * const argv[]);
int cmd_merge(int argc, char * const argv[]);
void usage_newfs();
int cmd_newfs(int argc, char * const argv[]);
int cmd_pull(int argc, char * const argv[]);
int cmd_rebuildindex(int argc, char * const argv[]);
int cmd_rebuildrefs(int argc, char * const argv[]);
int cmd_remote(int argc, char * const argv[]);
void usage_removefs();
int cmd_removefs(int argc, char * const argv[]);
int cmd_removekey(int argc, char * const argv[]);
void usage_replicate(void);
int cmd_replicate(int argc, char * const argv[]);
int cmd_setkey(int argc, char * const argv[]);
int cmd_show(int argc, char * const argv[]);
void usage_snapshot(void);
int cmd_snapshot(int argc, char * const argv[]);
int cmd_snapshots(int argc, char * const argv[]);
int cmd_status(int argc, char * const argv[]);
int cmd_tip(int argc, char * const argv[]);
int cmd_varlink(int argc, char * const argv[]);

// Debug Operations
int cmd_fsck(int argc, char * const argv[]);
int cmd_purgesnapshot(int argc, char * const argv[]);
int cmd_sshserver(int argc, char * const argv[]); // Internal
static int cmd_help(int argc, char * const argv[]);
static int cmd_version(int argc, char * const argv[]);

static Cmd commands[] = {
    {
        "addkey",
        "Add a trusted public key to the repository",
        cmd_addkey,
        NULL,
        CMD_EXPERIMENTAL,
    },
    {
        "branch",
        "Set or print current branch",
        cmd_branch,
        NULL,
        CMD_EXPERIMENTAL,
    },
    {
        "branches",
        "List all available branches",
        cmd_branches,
        NULL,
        CMD_EXPERIMENTAL,
    },
    {
        "checkout",
        "Checkout a revision of the repository",
        cmd_checkout,
        NULL,
        CMD_EXPERIMENTAL | CMD_NEED_FUSE,
    },
    {
        "cleanup",
        "Cleanup a repository after a FUSE crash",
        cmd_cleanup,
        usage_cleanup,
        CMD_DEBUG,
    },
    {
        "diff",
        "Display a diff of the pending changes (NS)",
        cmd_diff,
        NULL,
        CMD_DEBUG,
    },
    {
        "filelog",
        "Display a log of change to the specified file (NS)",
        cmd_filelog,
        NULL,
        CMD_DEBUG,
    },
    {
        "findheads",
        "Find lost heads (NS)",
        cmd_findheads,
        NULL,
        CMD_DEBUG,
    },
    {
        "gc",
        "Reclaim unused space (NS)",
        cmd_gc,
        NULL,
        CMD_DEBUG,
    },
    {
        "graft",
        "Graft a subtree from a repository into the local repository (NS)",
        cmd_graft,
        usage_graft,
        CMD_DEBUG, /* 0 to allow aliasing of 'cp' */
    },
    {
        "help",
        "Show help for a given topic",
        cmd_help,
        NULL,
        0,
    },
    {
        "list",
        "List local file systems",
        cmd_list,
        usage_list,
        0,
    },
    {
        "listkeys",
        "Display a list of trusted public keys",
        cmd_listkeys,
        NULL,
        CMD_EXPERIMENTAL,
    },
    {
        "log",
        "Display a log of commits to the repository",
        cmd_log,
        NULL,
        CMD_NEED_FUSE,
    },
    {
        "merge",
        "Merge two heads",
        cmd_merge,
        NULL,
        CMD_NEED_FUSE,
    },
    {
        "newfs",
        "Create a new file system",
        cmd_newfs,
        usage_newfs,
        0,
    },
    {
        "pull",
        "Pull changes from a repository",
        cmd_pull,
        NULL,
        CMD_NEED_FUSE,
    },
    {
        "purgesnapshot",
        "Purge snapshot (NS)",
        cmd_purgesnapshot,
        NULL,
        CMD_DEBUG,
    },
    {
        "remote",
        "Remote connection management",
        cmd_remote,
        NULL,
        CMD_NEED_FUSE,
    },
    {
        "removefs",
        "Remove a local replica",
        cmd_removefs,
        usage_removefs,
        0,
    },
    {
        "removekey",
        "Remove a public key from the repository",
        cmd_removekey,
        NULL,
        CMD_EXPERIMENTAL,
    },
    {
        "replicate",
        "Create a local replica",
        cmd_replicate,
        usage_replicate,
        0,
    },
    {
        "setkey",
        "Set the repository private key for signing commits",
        cmd_setkey,
        NULL,
        CMD_EXPERIMENTAL,
    },
    {
        "show",
        "Show repository information",
        cmd_show,
        NULL,
        CMD_NEED_FUSE,
    },
    {
        "snapshot",
        "Create a repository snapshot",
        cmd_snapshot,
        usage_snapshot,
        CMD_NEED_FUSE,
    },
    {
        "snapshots",
        "List all snapshots available in the repository",
        cmd_snapshots,
        NULL,
        CMD_NEED_FUSE,
    },
    {
        "status",
        "Scan for changes since last commit",
        cmd_status,
        NULL,
        CMD_NEED_FUSE,
    },
    {
        "tip",
        "Print the latest commit on this branch",
        cmd_tip,
        NULL,
        CMD_NEED_FUSE,
    },
    {
        "varlink",
        "Get, set, list varlink variables",
        cmd_varlink,
        NULL,
        CMD_NEED_FUSE,
    },
    /* Internal (always hidden) */
    {
        "sshserver",
        NULL, // "Run a simple stdin/out server, intended for SSH access",
        cmd_sshserver,
        NULL,
        0,
    },
    /* Debugging */
    {
        "fsck",
        "Check internal state of FUSE file system",
        cmd_fsck,
        NULL,
        CMD_NEED_FUSE | CMD_DEBUG,
    },
    {
        "version",
        "Show version information",
        cmd_version,
        NULL,
        CMD_DEBUG,
    },
    { NULL, NULL, NULL, NULL }
};

static int
lookupcmd(const char *cmd)
{
    int i;

    for (i = 0; commands[i].name != NULL; i++)
    {
        if (strcmp(commands[i].name, cmd) == 0)
            return i;
    }

    return -1;
}

static int
cmd_help(int argc, char * const argv[])
{
    int i = 0;

    if (argc >= 2) {
        i = lookupcmd(argv[1]);
        if (i != -1 && commands[i].usage != NULL) {
            commands[i].usage();
            return 0;
        }
        if (i == -1) {
            printf("Unknown command '%s'\n", argv[1]);
        } else {
            printf("No help for command '%s'\n", argv[1]);
        }
        return 0;
    }

    printf("Ori Distributed Personal File System (%s) - Command Line Interface\n\n",
            ORI_VERSION_STR);
    printf("Available commands:\n");
    for (i = 0; commands[i].name != NULL; i++)
    {
        const char *flag = "";
#ifndef DEBUG
        if (commands[i].flags & (CMD_DEBUG | CMD_EXPERIMENTAL))
            continue;
#endif /* DEBUG */
        if (commands[i].flags & CMD_DEBUG)
            flag = " (DEBUG)";
        if (commands[i].flags & CMD_EXPERIMENTAL)
            flag = " (EXPERIMENTAL)";
        if (commands[i].desc != NULL)
            printf("%-15s %s%s\n", commands[i].name, commands[i].desc, flag);
    }

    printf("\nPlease report bugs to orifs-devel@stanford.edu\n");
    printf("Website: http://ori.scs.stanford.edu/\n");

    return 0;
}

static int
cmd_version(int argc, char * const argv[])
{
    printf("Ori Distributed Personal File System (%s) - Command Line Interface\n",
            ORI_VERSION_STR);
#ifdef GIT_VERSION
    printf("Git Commit Id: " GIT_VERSION "\n");
#endif
#if defined(DEBUG) || defined(ORI_DEBUG)
    printf("Build: DEBUG\n");
#elif defined(ORI_PERF)
    printf("Build: PERF\n");
#else
    printf("Build: RELEASE\n");
#endif

    return 0;
}

int
main(int argc, char *argv[])
{
    int idx;

    if (argc == 1) {
        return cmd_help(0, NULL);
    }

    idx = lookupcmd(argv[1]);
    if (idx == -1) {
        printf("Unknown command '%s'\n", argv[1]);
        cmd_help(0, NULL);
        return 1;
    }

#if defined(DEBUG) || defined(ORI_PERF)
    string logPath = Util_GetHome() + "/.ori/oricli.log";
    ori_open_log(logPath);
#endif

    client = NULL;
    if (commands[idx].flags & CMD_NEED_FUSE) {
        string repoPath;

        if (!OF_HasFuse()) {
            printf("This command must be run on a mounted file system!\n");
            exit(1);
        }

        repoPath = OF_RepoPath();
        if (repoPath == "") {
            printf("Cannot find repository path!\n");
            exit(1);
        }

        try {
            client = new UDSClient(repoPath);
            if (client->connect() < 0) {
                printf("Failed to connect to UDS Repository!\n");
                exit(1);
            }

            repository = UDSRepo(client);
        } catch (exception &e) {
            printf("Failed to connect to FUSE: %s\n", e.what());
            exit(1);
        }
    }

    DLOG("Executing '%s'", argv[1]);
    int status = commands[idx].cmd(argc-1, (char * const*)argv+1);

    if (client)
        delete client;

    return status;
}

<|endoftext|>


<commit_before>TCPClient client;

void ipArrayFromString(byte ipArray[], String ipString) {
  int dot1 = ipString.indexOf('.');
  ipArray[0] = ipString.substring(0, dot1).toInt();
  int dot2 = ipString.indexOf('.', dot1 + 1);
  ipArray[1] = ipString.substring(dot1 + 1, dot2).toInt();
  dot1 = ipString.indexOf('.', dot2 + 1);
  ipArray[2] = ipString.substring(dot2 + 1, dot1).toInt();
  ipArray[3] = ipString.substring(dot1 + 1).toInt();
}

int connectToMyServer(String params) {
  //parse data
  int colonIndex = params.indexOf(":");
  String ip = params.substring(0, colonIndex);
  String port = params.substring(colonIndex+1, params.length());

  byte serverAddress[4];
  ipArrayFromString(serverAddress, ip);
  int serverPort = port.toInt();
  if (client.connect(serverAddress, serverPort)) {
    return 1; // successfully connected
  } else {
    return -1; // failed to connect
  }
}

void setup() {
  Spark.function("connect", connectToMyServer);

}

void loop() {
  if (client.connected()) {
    if (client.available()) {
      // parse and execute commands

      int action = client.read();

      if (action == 0x00) {
        // TODO: pinMode
        int pin = client.read();
        int mode = client.read();

        if (mode == 0x00) {
          pinMode(pin, INPUT);
        } else if (mode == 0x01) {
          pinMode(pin, INPUT_PULLUP);
        } else if (mode == 0x02) {
          pinMode(pin, INPUT_PULLDOWN);
        } else if (mode == 0x03) {
          pinMode(pin, OUTPUT);
        }
      } else if (action == 0x01) {
        // digitalWrite
        int pin = client.read();
        int value = client.read();
        digitalWrite(pin, value);
      } else if (action == 0x02) {
        // analogWrite
        int pin = client.read();
        int value = client.read();
        analogWrite(pin, value);
      } else if (action == 0x03) {
        // digitalRead
        int pin = client.read();
        int val = digitalRead(pin);
        client.write(0x03);
        client.write(pin);
        client.write(val);
      } else if (action == 0x04) {
        // analogRead
        int pin = client.read();
        int val = analogRead(pin);
        client.write(0x04);
        client.write(pin);
        client.write(val);
      }
    }
  }
}<commit_msg>Wire interface is built out. (resolved)<commit_after>TCPClient client;

void ipArrayFromString(byte ipArray[], String ipString) {
  int dot1 = ipString.indexOf('.');
  ipArray[0] = ipString.substring(0, dot1).toInt();
  int dot2 = ipString.indexOf('.', dot1 + 1);
  ipArray[1] = ipString.substring(dot1 + 1, dot2).toInt();
  dot1 = ipString.indexOf('.', dot2 + 1);
  ipArray[2] = ipString.substring(dot2 + 1, dot1).toInt();
  ipArray[3] = ipString.substring(dot1 + 1).toInt();
}

int connectToMyServer(String params) {
  //parse data
  int colonIndex = params.indexOf(":");
  String ip = params.substring(0, colonIndex);
  String port = params.substring(colonIndex+1, params.length());

  byte serverAddress[4];
  ipArrayFromString(serverAddress, ip);
  int serverPort = port.toInt();
  if (client.connect(serverAddress, serverPort)) {
    return 1; // successfully connected
  } else {
    return -1; // failed to connect
  }
}

void setup() {
  Spark.function("connect", connectToMyServer);

}

void loop() {
  if (client.connected()) {
    if (client.available()) {
      // parse and execute commands

      int action = client.read();
      if(DEBUG)
        Serial.println("Action received: "+('0'+action));
      char charVal;
      int pin, mode, val, type, speed, address, stop;
      switch (action) {
        case 0x00:  // pinMode
          pin = client.read();
          mode = client.read();
          //mode is modeled after Standard Firmata
          if (mode == 0x00) {
            pinMode(pin, INPUT);
          } else if (mode == 0x02) {
            pinMode(pin, INPUT_PULLUP);
          } else if (mode == 0x03) {
            pinMode(pin, INPUT_PULLDOWN);
          } else if (mode == 0x01) {
            pinMode(pin, OUTPUT);
          }
          break;
        case 0x01:  // digitalWrite
          pin = client.read();
          val = client.read();
          digitalWrite(pin, val);
          break;
        case 0x02:  // analogWrite
          pin = client.read();
          val = client.read();
          analogWrite(pin, val);
          break;
        case 0x03:  // digitalRead
          pin = client.read();
          val = digitalRead(pin);
          client.write(0x03);
          client.write(pin);
          client.write(val);
          break;
        case 0x04:  // analogRead
          pin = client.read();
          val = analogRead(pin);
          client.write(0x04);
          client.write(pin);
          client.write(val);
          break;

        // Serial API
        case 0x10:  // serial.begin
           type = client.read();
           speed = client.read();
          if (type == 0) {
            Serial.begin(SerialSpeed[speed]);
          } else {
            Serial1.begin(SerialSpeed[speed]);
          }
          break;
        case 0x12:  // serial.end
          type = client.read();
          if (type == 0) {
            Serial.end();
          } else {
            Serial1.end();
          }
          break;
        case 0x13:  // serial.peek
          type = client.read();
          if (type == 0) {
            val = Serial.peek();
          } else {
            val = Serial1.peek();
          }
          client.write(0x07);
          client.write(type);
          client.write(val);
          break;
        case 0x14:  // serial.available()
          type = client.read();
          if (type == 0) {
            val = Serial.available();
          } else {
            val = Serial1.available();
          }
          client.write(0x07);
          client.write(type);
          client.write(val);
          break;
        case 0x15:  // serial.write
          type = client.read();
          len = client.read();
          while (i = 0; i < len; i++) {
            if (type ==0) {
              Serial.write(client.read());
            } else {
              Serial1.write(client.read());
            }
          }
          break;
        case 0x16: // serial.read
          type = client.read();
          if (type == 0) {
            val = Serial.read();
          } else {
            val = Serial1.read();
          }
          client.write(0x16);
          client.write(type);
          client.write(val);
          break;
        case 0x17: // serial.flush
          type = client.read();
          if (type == 0) {
            Serial.flush();
          } else {
            Serial1.flush();
          }
          break;

        // SPI API
        case 0x20:  // SPI.begin
          SPI.begin();
          break;
        case 0x21:  // SPI.end
          SPI.end();
          break;
        case 0x22:  // SPI.setBitOrder
          type = client.read();
          SPI.setBitOrder((type ? MSBFIRST : LSBFIRST));
          break;
        case 0x22:  // SPI.setClockDivider
          val = client.read();
          if (val == 0) {
            SPI.setClockDivider(SPI_CLOCK_DIV2);
          } else if (val == 1) {
            SPI.setClockDivider(SPI_CLOCK_DIV4);
          } else if (val == 2) {
            SPI.setClockDivider(SPI_CLOCK_DIV8);
          } else if (val == 3) {
            SPI.setClockDivider(SPI_CLOCK_DIV16);
          } else if (val == 4) {
            SPI.setClockDivider(SPI_CLOCK_DIV32);
          } else if (val == 5) {
            SPI.setClockDivider(SPI_CLOCK_DIV64);
          } else if (val == 6) {
            SPI.setClockDivider(SPI_CLOCK_DIV128);
          } else if (val == 7) {
            SPI.setClockDivider(SPI_CLOCK_DIV256);
          }
          break;

        case 0x23:  // SPI.setDataMode
          val = client.read();
          if (val == 0) {
            SPI.setDataMode(SPI_MODE0);
          } else if (val == 1) {
            SPI.setDataMode(SPI_MODE1);
          } else if (val == 2) {
            SPI.setDataMode(SPI_MODE2);
          } else if (val == 3) {
            SPI.setDataMode(SPI_MODE3);
          }
          break;

        case 0x24:  // SPI.transfer
          val = client.read();
          SPI.transfer(val);
          break;

        // Wire API
        case 0x30:  // Wire.begin
          address = client.read();
          if (address == 0) {
            Wire.begin();
          } else {
            Wire.begin(address);
          }
          break;
        case 0x31:  // Wire.requestFrom
          address = client.read();
          int quantity = client.read();
          stop = client.read();

          Wire.requestFrom(address, quantity, stop);
          break;
        case 0x32:  // Wire.beginTransmission
          address = client.read();
          Wire.beginTransmission(address);
          break;
        case 0x33:  // Wire.endTransmission
          stop = client.read();
          val = Wire.endTransmission(stop);
          client.write(0x33);
          client.write(val);
          break;
        case 0x34:  // Wire.write
          len = client.read();
          char wireData[len];
          for (i = 0; i< len; i++) {
            wireData[i] = client.read();
          }
          val = Wire.write(data, len);
          client.write(0x34);
          client.write(val);
          break;
        case 0x35:  // Wire.available
          val = Wire.available();
          client.write(0x35);
          client.write(val);
          break;
        case 0x36:  // Wire.read
          val = Wire.read();
          client.write(0x36);
          client.write(val);
          break;
      }
    }
  }
}
<|endoftext|>


<commit_before>#include "plugin.h"
#include <windows.h>
#include <stdio.h>
#include "../TitanHide/TitanHide.h"

static DWORD pid = 0;
static bool hidden = false;

static void TitanHideCall(HIDE_COMMAND Command)
{
    HANDLE hDevice = CreateFileA("\\\\.\\TitanHide", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
    if(hDevice == INVALID_HANDLE_VALUE)
    {
        _plugin_logputs("[" PLUGIN_NAME "] Could not open TitanHide handle...");
        return;
    }
    HIDE_INFO HideInfo;
    HideInfo.Command = Command;
    HideInfo.Pid = pid;
    HideInfo.Type = 0xFFFFFFFF;
    DWORD written = 0;
    if(WriteFile(hDevice, &HideInfo, sizeof(HIDE_INFO), &written, 0))
    {
        _plugin_logputs("[" PLUGIN_NAME "] Process hidden!");
        hidden = true;
    }
    else
        _plugin_logputs("[" PLUGIN_NAME "] WriteFile error...");
    CloseHandle(hDevice);
}

PLUG_EXPORT void CBCREATEPROCESS(CBTYPE cbType, PLUG_CB_CREATEPROCESS* info)
{
    pid = info->fdProcessInfo->dwProcessId;
}

PLUG_EXPORT void CBATTACH(CBTYPE cbType, PLUG_CB_ATTACH* info)
{
    pid = info->dwProcessId;
}

PLUG_EXPORT void CBSYSTEMBREAKPOINT(CBTYPE cbType, PLUG_CB_SYSTEMBREAKPOINT* info)
{
    DbgCmdExec("TitanHide");
}

PLUG_EXPORT void CBSTOPDEBUG(CBTYPE cbType, PLUG_CB_STOPDEBUG* info)
{
    if(hidden)
    {
        hidden = false;
        _plugin_logprintf("[" PLUGIN_NAME "] Unhiding PID %X (%ud)\n", pid, pid);
        TitanHideCall(UnhidePid);
    }
}

static bool cbTitanHide(int argc, char* argv[])
{
    if(!hidden)
    {
        _plugin_logprintf("[" PLUGIN_NAME "] Hiding PID %X (%ud)\n", pid, pid);
        TitanHideCall(HidePid);
        DbgCmdExec("hide");
    }
    else
    {
        _plugin_logprintf("[" PLUGIN_NAME "] Unhiding PID %X (%ud)\n", pid, pid);
        TitanHideCall(UnhidePid);
    }
    return true;
}

void TitanHideInit(PLUG_INITSTRUCT* initStruct)
{
    if(!_plugin_registercommand(pluginHandle, "TitanHide", cbTitanHide, false))
        puts("[" PLUGIN_NAME "] Error registering command!");
}

void TitanHideStop()
{
    _plugin_unregistercommand(pluginHandle, "TitanHide");
}
<commit_msg>improve TitanHide plugin for x64dbg to work correctly on restart and to allow custom options<commit_after>#include "plugin.h"
#include <windows.h>
#include <stdio.h>
#include "../TitanHide/TitanHide.h"

static DWORD pid = 0;
static bool hidden = false;

static ULONG GetTitanHideOptions()
{
    duint options = 0;
    if (!BridgeSettingGetUint("TitanHide", "Options", &options))
        options = 0xffffffff;
    return (ULONG)options;
}

static bool TitanHideCall(HIDE_COMMAND Command)
{
    HANDLE hDevice = CreateFileA("\\\\.\\TitanHide", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
    if(hDevice == INVALID_HANDLE_VALUE)
    {
        _plugin_logputs("[" PLUGIN_NAME "] Could not open TitanHide handle...");
        return false;
    }
    HIDE_INFO HideInfo;
    HideInfo.Command = Command;
    HideInfo.Pid = pid;
    HideInfo.Type = GetTitanHideOptions();
    DWORD written = 0;
    auto result = false;
    if(WriteFile(hDevice, &HideInfo, sizeof(HIDE_INFO), &written, 0))
    {
        _plugin_logprintf("[" PLUGIN_NAME "] Process %shidden!\n", Command == UnhidePid ? "un" : "");
        result = true;
    }
    else
    {
        _plugin_logputs("[" PLUGIN_NAME "] WriteFile error...");
    }
    CloseHandle(hDevice);
    return result;
}

PLUG_EXPORT void CBCREATEPROCESS(CBTYPE cbType, PLUG_CB_CREATEPROCESS* info)
{
    pid = info->fdProcessInfo->dwProcessId;
}

PLUG_EXPORT void CBATTACH(CBTYPE cbType, PLUG_CB_ATTACH* info)
{
    pid = info->dwProcessId;
}

PLUG_EXPORT void CBSYSTEMBREAKPOINT(CBTYPE cbType, PLUG_CB_SYSTEMBREAKPOINT* info)
{
    DbgCmdExecDirect("TitanHide");
}

PLUG_EXPORT void CBSTOPDEBUG(CBTYPE cbType, PLUG_CB_STOPDEBUG* info)
{
    if(hidden)
    {
        hidden = false;
        _plugin_logprintf("[" PLUGIN_NAME "] Unhiding PID %X (%ud)\n", pid, pid);
        TitanHideCall(UnhidePid);
    }
}

static bool cbTitanHide(int argc, char* argv[])
{
    if(!hidden)
    {
        _plugin_logprintf("[" PLUGIN_NAME "] Hiding PID %X (%ud)\n", pid, pid);
        if (TitanHideCall(HidePid))
        {
            DbgCmdExecDirect("hide");
            hidden = true;
        }
    }
    else
    {
        _plugin_logprintf("[" PLUGIN_NAME "] Unhiding PID %X (%ud)\n", pid, pid);
        TitanHideCall(UnhidePid);
    }
    return true;
}

static bool cbTitanHideOptions(int argc, char* argv[])
{
    if (argc < 2)
    {
        _plugin_logprintf("[" PLUGIN_NAME "] Options: 0x%08X\n", GetTitanHideOptions());
    }
    else
    {
        duint options = DbgValFromString(argv[1]);
        BridgeSettingSetUint("TitanHide", "Options", options & 0xffffffff);
        if (hidden)
            TitanHideCall(HidePid);
        _plugin_logprintf("[" PLUGIN_NAME "] New options: 0x%08X\n", GetTitanHideOptions());
    }
    return true;
}

void TitanHideInit(PLUG_INITSTRUCT* initStruct)
{
    if(!_plugin_registercommand(pluginHandle, "TitanHide", cbTitanHide, false))
        puts("[" PLUGIN_NAME "] Error registering command 'TitanHide'!");
    if (!_plugin_registercommand(pluginHandle, "TitanHideOptions", cbTitanHideOptions, false))
        puts("[" PLUGIN_NAME "] Error registering command 'TitanHideOptions'!");
}

void TitanHideStop()
{
    _plugin_unregistercommand(pluginHandle, "TitanHideOptions");
    _plugin_unregistercommand(pluginHandle, "TitanHide");
}
<|endoftext|>