Skip to content

Commit 69a20e2

Browse files
feat: Adding support for more Kiiroo Gen2.1 devices
New UUIDs for Pearl2.1 and Esca2. Name mapping for Titan1.1 Merged the 2 Kiiroo Gen 2.1 protcol drivers into the same class. This makes it way simpler to access the vibes on the Titan as well as use the LinearCmd support.
1 parent fb73beb commit 69a20e2

File tree

6 files changed

+204
-138
lines changed

6 files changed

+204
-138
lines changed

Buttplug.Test/Devices/Protocols/KiirooGen21VibeTests.cs

+38-10
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,29 @@ public class KiirooGen21VibeTests
2929
[Test]
3030
publicasyncTaskTestAllowedMessages()
3131
{
32-
foreach(variteminKiirooGen21VibeProtocol.DevInfos)
32+
foreach(variteminKiirooGen21Protocol.DevInfos)
3333
{
34+
if(item.Value.VibeCount==0)
35+
{
36+
continue;
37+
}
38+
3439
vartestUtil=newProtocolTestUtils();
35-
awaittestUtil.SetupTest<KiirooGen21VibeProtocol>(item.Key);
36-
testUtil.TestDeviceAllowedMessages(newDictionary<Type,uint>()
40+
awaittestUtil.SetupTest<KiirooGen21Protocol>(item.Key);
41+
varexpected=newDictionary<Type,uint>()
3742
{
3843
{typeof(StopDeviceCmd),0},
3944
{typeof(SingleMotorVibrateCmd),0},
4045
{typeof(VibrateCmd),item.Value.VibeCount},
41-
});
46+
};
47+
48+
if(item.Value.HasLinear)
49+
{
50+
expected.Add(typeof(LinearCmd),1);
51+
expected.Add(typeof(FleshlightLaunchFW12Cmd),0);
52+
}
53+
54+
testUtil.TestDeviceAllowedMessages(expected);
4255
}
4356
}
4457

@@ -47,10 +60,15 @@ public async Task TestAllowedMessages()
4760
[Test]
4861
publicasyncTaskTestSingleMotorVibrateCmd()
4962
{
50-
foreach(variteminKiirooGen21VibeProtocol.DevInfos)
63+
foreach(variteminKiirooGen21Protocol.DevInfos)
5164
{
65+
if(item.Value.VibeCount==0)
66+
{
67+
continue;
68+
}
69+
5270
vartestUtil=newProtocolTestUtils();
53-
awaittestUtil.SetupTest<KiirooGen21VibeProtocol>(item.Key);
71+
awaittestUtil.SetupTest<KiirooGen21Protocol>(item.Key);
5472
varexpected=newbyte[]{1,0};
5573
for(vari=0u;i<item.Value.VibeCount;++i)
5674
{
@@ -69,10 +87,15 @@ await testUtil.TestDeviceMessage(new SingleMotorVibrateCmd(4, 0.5),
6987
[Test]
7088
publicasyncTaskTestVibrateCmd()
7189
{
72-
foreach(variteminKiirooGen21VibeProtocol.DevInfos)
90+
foreach(variteminKiirooGen21Protocol.DevInfos)
7391
{
92+
if(item.Value.VibeCount==0)
93+
{
94+
continue;
95+
}
96+
7497
vartestUtil=newProtocolTestUtils();
75-
awaittestUtil.SetupTest<KiirooGen21VibeProtocol>(item.Key);
98+
awaittestUtil.SetupTest<KiirooGen21Protocol>(item.Key);
7699
varspeeds=new[]{0.25,0.5,0.75};
77100
varfeatures=newList<VibrateCmd.VibrateSubcommand>();
78101
for(vari=0u;i<item.Value.VibeCount;++i)
@@ -98,10 +121,15 @@ await testUtil.TestDeviceMessage(new VibrateCmd(4, features),
98121
[Test]
99122
publicasyncTaskTestInvalidCmds()
100123
{
101-
foreach(variteminKiirooGen21VibeProtocol.DevInfos)
124+
foreach(variteminKiirooGen21Protocol.DevInfos)
102125
{
126+
if(item.Value.VibeCount==0)
127+
{
128+
continue;
129+
}
130+
103131
vartestUtil=newProtocolTestUtils();
104-
awaittestUtil.SetupTest<KiirooGen21VibeProtocol>(item.Key);
132+
awaittestUtil.SetupTest<KiirooGen21Protocol>(item.Key);
105133
testUtil.TestInvalidVibrateCmd(item.Value.VibeCount);
106134
}
107135
}

Buttplug/Devices/Configuration/DeviceConfigurationManager.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ protected DeviceConfigurationManager()
5050
AddProtocol("cueme",typeof(CuemeProtocol));
5151
AddProtocol("kiiroo-v1",typeof(KiirooGen1Protocol));
5252
AddProtocol("kiiroo-v2-vibrator",typeof(KiirooGen2VibeProtocol));
53-
AddProtocol("kiiroo-v21-vibrator",typeof(KiirooGen21VibeProtocol));
53+
AddProtocol("kiiroo-v21",typeof(KiirooGen21Protocol));
54+
AddProtocol("kiiroo-v21-vibrator",typeof(KiirooGen21Protocol));// 2 names for backwards compatibility
5455
AddProtocol("lelo-f1s",typeof(LeloF1sProtocol));
5556
AddProtocol("libo",typeof(LiBoProtocol));
5657
AddProtocol("lovehoney-desire",typeof(LovehoneyDesireProtocol));
@@ -64,7 +65,6 @@ protected DeviceConfigurationManager()
6465
AddProtocol("youcups",typeof(YoucupsProtocol));
6566
AddProtocol("vorze-cyclone-x",typeof(CycloneX10Protocol));
6667
AddProtocol("youou",typeof(YououProtocol));
67-
AddProtocol("kiiroo-v21",typeof(KiirooGen21Protocol));
6868
AddProtocol("realtouch",typeof(RealTouchProtocol));
6969
AddProtocol("svakom",typeof(SvakomProtocol));
7070
AddProtocol("realov",typeof(RealovProtocol));

Buttplug/Devices/Protocols/KiirooGen21Protocol.cs

+152-10
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
// <copyright file="KiirooOnyx21Protocol.cs" company="Nonpolynomial Labs LLC">
1+
// <copyright file="KiirooGen21Protocol.cs" company="Nonpolynomial Labs LLC">
22
// Buttplug C# Source Code File - Visit https://buttplug.io for more info about the project.
33
// Copyright (c) Nonpolynomial Labs LLC. All rights reserved.
44
// Licensed under the BSD 3-Clause license. See LICENSE file in the project root for full license information.
55
// </copyright>
66

77
usingSystem;
8+
usingSystem.Collections.Generic;
89
usingSystem.Threading;
910
usingSystem.Threading.Tasks;
1011
usingButtplug.Core.Logging;
@@ -13,26 +14,167 @@
1314

1415
namespaceButtplug.Devices.Protocols
1516
{
17+
// ReSharper disable once InconsistentNaming
1618
internalclassKiirooGen21Protocol:ButtplugDeviceProtocol
1719
{
20+
privatereadonlydouble[]_vibratorSpeeds={0,0,0};
1821
privatedouble_lastPosition;
1922

23+
// ReSharper disable once InconsistentNaming
24+
internalstructKiirooGen21Type
25+
{
26+
publicstringBrand;
27+
publicstringName;
28+
publicboolHasLinear;
29+
publicuintVibeCount;
30+
publicuint[]VibeOrder;
31+
}
32+
33+
internalstaticreadonlyDictionary<string,KiirooGen21Type>DevInfos=newDictionary<string,KiirooGen21Type>()
34+
{
35+
{
36+
"Cliona",
37+
newKiirooGen21Type
38+
{
39+
Brand="Kiiroo",
40+
Name="Cliona",
41+
HasLinear=false,
42+
VibeCount=1,
43+
VibeOrder=new[]{0u,1u,2u},
44+
}
45+
},
46+
{
47+
"Pearl2.1",
48+
newKiirooGen21Type
49+
{
50+
Brand="Kiiroo",
51+
Name="Pearl 2.1",
52+
HasLinear=false,
53+
VibeCount=1,
54+
VibeOrder=new[]{0u,1u,2u},
55+
}
56+
},
57+
{
58+
"OhMiBod 4.0",
59+
newKiirooGen21Type
60+
{
61+
Brand="OhMiBod",
62+
Name="Esca 2",
63+
HasLinear=false,
64+
VibeCount=1,
65+
VibeOrder=new[]{0u,1u,2u},
66+
}
67+
},
68+
{
69+
"Onyx2.1",
70+
newKiirooGen21Type
71+
{
72+
Brand="Kiiroo",
73+
Name="Onyx 2.1",
74+
HasLinear=true,
75+
VibeCount=0,
76+
VibeOrder=new[]{0u,1u,2u},
77+
}
78+
},
79+
{
80+
"Titan1.1",
81+
newKiirooGen21Type
82+
{
83+
Brand="Kiiroo",
84+
Name="Titan 1.1",
85+
HasLinear=true,
86+
VibeCount=1,// actually 3
87+
VibeOrder=new[]{0u,1u,2u},
88+
}
89+
},
90+
};
91+
92+
privatereadonlyKiirooGen21Type_devInfo;
93+
2094
publicKiirooGen21Protocol([NotNull]IButtplugLogManageraLogManager,
21-
IButtplugDeviceImplaInterface)
95+
[NotNull]IButtplugDeviceImplaInterface)
2296
:base(aLogManager,
23-
"Kiiroo Onyx2.1",
24-
aInterface)
97+
"Kiiroo Unknown",
98+
aInterface)
2599
{
26-
// Setup message function array
27-
AddMessageHandler<FleshlightLaunchFW12Cmd>(HandleFleshlightLaunchFW12Cmd);
28-
AddMessageHandler<LinearCmd>(HandleLinearCmd,newMessageAttributes(){FeatureCount=1});
100+
if(DevInfos.ContainsKey(aInterface.Name))
101+
{
102+
Name=$"{DevInfos[aInterface.Name].Brand}{DevInfos[aInterface.Name].Name}";
103+
_devInfo=DevInfos[aInterface.Name];
104+
}
105+
else
106+
{
107+
BpLogger.Warn($"Cannot identify device {Name}, defaulting to Pearl2 settings.");
108+
_devInfo=DevInfos["Pearl2.1"];
109+
}
110+
29111
AddMessageHandler<StopDeviceCmd>(HandleStopDeviceCmd);
112+
113+
if(_devInfo.VibeCount>0)
114+
{
115+
AddMessageHandler<VibrateCmd>(HandleVibrateCmd,
116+
newMessageAttributes{FeatureCount=_devInfo.VibeCount});
117+
AddMessageHandler<SingleMotorVibrateCmd>(HandleSingleMotorVibrateCmd);
118+
}
119+
120+
if(_devInfo.HasLinear)
121+
{
122+
AddMessageHandler<LinearCmd>(HandleLinearCmd,
123+
newMessageAttributes{FeatureCount=1});
124+
AddMessageHandler<FleshlightLaunchFW12Cmd>(HandleFleshlightLaunchFW12Cmd);
125+
}
30126
}
31127

32-
privateTask<ButtplugMessage>HandleStopDeviceCmd(ButtplugDeviceMessageaMsg,CancellationTokenaToken)
128+
privateasyncTask<ButtplugMessage>HandleStopDeviceCmd([NotNull]ButtplugDeviceMessageaMsg,CancellationTokenaToken)
33129
{
34-
BpLogger.Debug("Stopping Device "+Name);
35-
returnTask.FromResult<ButtplugMessage>(newOk(aMsg.Id));
130+
BpLogger.Debug($"Stopping Device {Name}");
131+
132+
if(_devInfo.VibeCount==0)
133+
{
134+
returnnewOk(aMsg.Id);
135+
}
136+
137+
returnawaitHandleVibrateCmd(VibrateCmd.Create(aMsg.DeviceIndex,aMsg.Id,0,_devInfo.VibeCount),aToken).ConfigureAwait(false);
138+
}
139+
140+
privateasyncTask<ButtplugMessage>HandleSingleMotorVibrateCmd([NotNull]ButtplugDeviceMessageaMsg,CancellationTokenaToken)
141+
{
142+
varcmdMsg=CheckMessageHandler<SingleMotorVibrateCmd>(aMsg);
143+
144+
returnawaitHandleVibrateCmd(VibrateCmd.Create(aMsg.DeviceIndex,aMsg.Id,cmdMsg.Speed,_devInfo.VibeCount),aToken).ConfigureAwait(false);
145+
}
146+
147+
privateasyncTask<ButtplugMessage>HandleVibrateCmd([NotNull]ButtplugDeviceMessageaMsg,CancellationTokenaToken)
148+
{
149+
varcmdMsg=CheckGenericMessageHandler<VibrateCmd>(aMsg,_devInfo.VibeCount);
150+
151+
varchanged=false;
152+
foreach(varviincmdMsg.Speeds)
153+
{
154+
if(Math.Abs(_vibratorSpeeds[vi.Index]-vi.Speed)<0.0001)
155+
{
156+
continue;
157+
}
158+
159+
_vibratorSpeeds[vi.Index]=vi.Speed;
160+
changed=true;
161+
}
162+
163+
if(!changed&&SentVibration)
164+
{
165+
returnnewOk(cmdMsg.Id);
166+
}
167+
168+
SentVibration=true;
169+
170+
vardata=new[]
171+
{
172+
(byte)0x01,
173+
(byte)Convert.ToUInt16(_vibratorSpeeds[_devInfo.VibeOrder[0]]*100),
174+
};
175+
176+
awaitInterface.WriteValueAsync(data,aToken).ConfigureAwait(false);
177+
returnnewOk(aMsg.Id);
36178
}
37179

38180
privateasyncTask<ButtplugMessage>HandleLinearCmd(ButtplugDeviceMessageaMsg,CancellationTokenaToken)

0 commit comments

Comments
 (0)
close