async private void StartTest()
    {
        if (ubiiClient == null)
        {
            Debug.LogError("UbiiClient not found!");
            return;
        }

        await ubiiClient.WaitForConnection();

        CreateUbiiSpecs();

        Ubii.Services.ServiceReply deviceRegistrationReply = await ubiiClient.RegisterDevice(ubiiDevice);

        if (deviceRegistrationReply.Device != null)
        {
            ubiiDevice = deviceRegistrationReply.Device;
        }

        await ubiiClient.Subscribe(topicTestPublishSubscribe, (Ubii.TopicData.TopicDataRecord record) =>
        {
            testPosition.Set((float)record.Vector3.X, (float)record.Vector3.Y, (float)record.Vector3.Z);
        });

        testRunning = true;
    }
    async private void RunTestSubscribePublish()
    {
        await ubiiClient.WaitForConnection();

        string topic   = "/" + ubiiClient.GetID() + "/unity3D_client/test/subcribe_publish_simple";
        bool   success = false;

        Action <TopicDataRecord> callback = (TopicDataRecord record) =>
        {
            success = record.Bool;
        };

        await ubiiClient.Subscribe(topic, callback);

        ubiiClient.Publish(new Ubii.TopicData.TopicData {
            TopicDataRecord = new Ubii.TopicData.TopicDataRecord {
                Topic = topic, Bool = true
            }
        });

        await Task.Delay(1000).ContinueWith(async(Task t) =>
        {
            await ubiiClient.Unsubscribe(topic, callback);

            if (success)
            {
                Debug.Log("RunTestSubscribePublish SUCCESS!");
            }
            else
            {
                Debug.LogError("RunTestSubscribePublish FAILURE!");
            }
        });
    }
    public async void Awake()
    {
        //singelton initialization
        if (instance != null)
        {
            Destroy(this);
        }
        else
        {
            instance = this;
        }

        texture_loader = FindObjectOfType <sc_texture_loader>();
        client         = FindObjectOfType <UbiiClient>();
        textures       = new Dictionary <string, Texture2D>();
        idle_gallery   = FindObjectOfType <sc_idle_gallery>();

        //initialize tools
        foreach (sc_tool t in tools)
        {
            t.initialize();
        }


        //load uv textures
        string path = "Textures/uv_1600x2560";

        byte[] data = (Resources.Load(path) as TextAsset).bytes;

        uv_1600x2560 = new Texture2D(1600, 2560, TextureFormat.RGBAFloat, false);
        uv_1600x2560.LoadRawTextureData(data);
        uv_1600x2560.Apply();


        path = "Textures/uv_1536x2048";
        data = (Resources.Load(path) as TextAsset).bytes;

        uv_1536x2048 = new Texture2D(1536, 2048, TextureFormat.RGBAFloat, false);
        uv_1536x2048.LoadRawTextureData(data);
        uv_1536x2048.Apply();


        //connect to server
        sc_save_management.loadNetConfig(out string ip, out string port);
        client.ip   = ip;
        client.port = int.Parse(port);

        await client.InitializeClient();

        await client.Subscribe("image name", receiveImageName);

        await client.Subscribe("image size", receiveImageSize);

        await client.Subscribe("image format", receiveImageFormat);

        await client.Subscribe("image", receiveImage);

        await client.Subscribe("command", receiveCommand);

        await client.Subscribe("gallery command", receiveGalleryCommand);

        await client.Subscribe("position", receivePositionData);

        await client.Subscribe("reset canvas", reset_canvas_requested);

        await client.Subscribe("uvimage resolution", receiveUVImage_resolution);

        await client.Subscribe("color", receiveColor);

        await client.Subscribe("brush size", receive_brush_size);

        await client.Subscribe("undo", receiveUndo);

        Debug.Log("connected");
        connected = true;
    }