static void characteristicUpdatedCallback(IntPtr nativep, string uuid, IntPtr valuep)
    {
        NeppiValue value =
            (NeppiValue)Marshal.PtrToStructure(valuep, typeof(NeppiValue));

        GCHandle            gch    = GCHandle.FromIntPtr(nativep);
        BLENativePeripheral native = (BLENativePeripheral)gch.Target;
        BLEPeripheral       peri   = native.client;

        if (peri != null && peri.CharacteristicUpdated != null)
        {
            peri.CharacteristicUpdated(uuid, value);
        }
    }
    void CharacteristicNotify(string uuid, NeppiValue v)
    {
        if (String.Equals(uuid, charactMPU, StringComparison.OrdinalIgnoreCase))
        {
            a_x = v.a_x;
            a_y = v.a_y;
            a_z = v.a_z;

            g_x = v.g_x;
            g_y = v.g_y;
            g_z = v.g_z;

            m_x = v.m_x;
            m_y = v.m_y;
            m_z = v.m_z;
            return;
        }

        if (String.Equals(uuid, charactColorHue, StringComparison.OrdinalIgnoreCase))
        {
            float H, S, V;
            Color.RGBToHSV(color, out H, out S, out V);
            color = Color.HSVToRGB((float)(v.color_hue / 360.0), 1.0f, V);
            return;
        }

        if (String.Equals(uuid, charactColorValue, StringComparison.OrdinalIgnoreCase))
        {
            double value = ((double)v.color_value) / 100.0;
            Debug.Assert(value >= 0.0 && value <= 1.0);
            // Brighten the intensity for Unity, as the unit is quite bright
            value = Math.Pow(value, 0.25);

            float H, S, V;
            Color.RGBToHSV(color, out H, out S, out V);
            color = Color.HSVToRGB(H, S, (float)value);
            return;
        }

        if (String.Equals(uuid, charactState, StringComparison.OrdinalIgnoreCase))
        {
            state      = (State)v.state;
            button_adc = v.button_adc;
        }
    }