public PeripheralConnectedDevice FindConnectedDevice(string address, int port, int session) { PeripheralConnectedDevice ret = null; if (session >= 0 && session < m_registeredDevices.Count) { foreach (PeripheralConnectedDevice d in m_registeredDevices[session].Target) { if (d.IsSame(address, port, d.TargetDeviceIndex)) { ret = d; break; } } } else { foreach (PeripheralDevice r in m_registeredDevices) { foreach (PeripheralConnectedDevice d in r.Target) { if (d.IsSame(address, port)) { return(d); } } } } return(ret); }
public bool IsSame(PeripheralConnectedDevice connectedDevice, int devidx) { if (connectedDevice.m_address == m_address && connectedDevice.m_port == m_port && devidx == m_devidx) { return(true); } return(false); }
public void ProcessBye(PeripheralConnectedDevice device) { if (null != device.Target) { device.Target.UnMatch(device); device.UnMatch(); } m_connectedDevices.Remove(device); }
public void UnMatch(PeripheralConnectedDevice connectedDevice) { OnDisconnected(connectedDevice); m_target.Remove(connectedDevice); if (m_target.Count == 0) { CancelInvoke("SendAlive"); } }
public void Match(PeripheralConnectedDevice connectedDevice) { if (m_target.Count == 0) { InvokeRepeating("SendAlive", 3.0f, 3.0f); } m_target.Add(connectedDevice); OnConnected(connectedDevice); }
public virtual bool IsAcceptable(PeripheralConnectedDevice cd) { bool ret = false; if (cd.IsCapable(m_requireAbility)) { // 登録されているすべてのabilityを満たすものを受理する. ret = true; } return(ret); }
public bool IsAlreadyConnected(PeripheralConnectedDevice connectedDevice, int devidx) { bool ret = false; foreach (PeripheralConnectedDevice d in m_target) { if (d.IsSame(connectedDevice, devidx)) { ret = true; break; } } return(ret); }
public bool TryMatching(PeripheralConnectedDevice device, int cnctDeviceIdx) { bool ret = false; for (int i = 0; i < m_registeredDevices.Count; i++) { if (TryMatching(device, i, cnctDeviceIdx)) { ret = true; break; } } return(ret); }
// アビリティを加味してPeripheralDeviceとPeripheralConnectedDeviceのマッチングをとる public bool TryMatching(PeripheralConnectedDevice connectedDevice, int regDeviceIdx, int cnctDeviceIdx) { bool ret = false; if (regDeviceIdx >= 0 && regDeviceIdx < m_registeredDevices.Count) { PeripheralDevice registeredDevice = m_registeredDevices[regDeviceIdx]; if (!registeredDevice.IsAlreadyConnected(connectedDevice, cnctDeviceIdx)) // 同じコネクションを2つ張らない { if (!connectedDevice.IsMatched && registeredDevice.IsAcceptable(connectedDevice)) { connectedDevice.Match(registeredDevice, cnctDeviceIdx); registeredDevice.Match(connectedDevice); ret = true; } } } else { foreach (PeripheralDevice r in m_registeredDevices) { if (!r.IsAlreadyConnected(connectedDevice, cnctDeviceIdx)) // 同じコネクションを2つ張らない { if (!connectedDevice.IsMatched && r.IsAcceptable(connectedDevice)) { connectedDevice.Match(r, cnctDeviceIdx); r.Match(connectedDevice); ret = true; break; } } } } return(ret); }
public virtual void OnDisconnected(PeripheralConnectedDevice d) { }
void OnReceive(string data, string address, int port) { if (!IsSelfPacket(address, port)) // 自分が送ったパケットは受けない { TextMesh text = GetComponentInChildren <TextMesh>(); if (null != text) { text.text = data + " from " + address + ":" + port; } PeripheralProtocol prtcl = JsonUtility.FromJson <PeripheralProtocol>(data); int devidx = GetDeviceIdxFromJson(data); //Debug.Log(data + " from " + address + ":" + port + " --- devidx: " + devidx); PeripheralConnectedDevice device = null; { // 接続しているPeripheralConnectedDeviceを取得する device = FindConnectedDevice(address, port, devidx); } switch (prtcl.pcmd) { case "search": { // {"pcmd":"search"} // 機器探索のためのトリガ。broadcastアドレスに送信する。 SendAvailable(address, port); Debug.Log("[GogyoNetwork]: Received search pcmd from " + address + ":" + port); } break; case "available": { // {"pcmd":"available","devidx":N,"ability":["ability_1","ability_2",...]} // 機器探索への応答をPeripheralDevice単位で行い,同時にPeripheralDeviceのアビリティの通達を行う。 PeripheralAvailable p = JsonUtility.FromJson <PeripheralAvailable>(data); if (!data.Contains("\"devidx\"")) { // HololensのJsonUtilityが、メンバーがいないときに0を代入してしまう問題への対策. p.devidx = -1; } if (null == device) { device = new PeripheralConnectedDevice(address, port, this, p.ability); foreach (string a in p.ability) { device.Ability.Add(a); } Debug.Log("[GogyoNetwork]: Received available pcmd from " + address + ":" + port + ", data: " + data); if (TryMatching(device, p.devidx)) { // 対応するデバイスみつかった. SendRequest(address, port, p.devidx, GetDeviceIndex(device.Target)); m_connectedDevices.Add(device); } } else { // 既に知ってるデバイスは無視する. } } break; case "request": { // {"pcmd":"request","devidx":N,"selfdevidx":M} // 接続要求の発行。発行元は接続を確立。devidxは要求先のデバイスインデックス。selfdevidxは要求元のデバイスインデックス。 PeripheralRequestProtocol p = JsonUtility.FromJson <PeripheralRequestProtocol>(data); if (!data.Contains("\"devidx\"")) { // HololensのJsonUtilityが、メンバーがいないときに0を代入してしまう問題への対策. p.devidx = -1; } Debug.Log("[GogyoNetwork]: Received request pcmd from " + address + ":" + port + ", devidx: " + p.devidx + ", selfdevidx: " + p.selfdevidx); if (p.devidx < m_registeredDevices.Count) { PeripheralConnectedDevice d = new PeripheralConnectedDevice(address, port, this); if (ForceMatching(d, p.devidx, p.selfdevidx)) { m_connectedDevices.Add(d); if (null != d.Target) { d.Target.OnRequested(); } } } } break; case "alive": if (null != device) { // {"pcmd":"request","devidx":N} // 生存確認用の通達。 Debug.Log("[GogyoNetwork]: Received alive pcmd from " + address + ":" + port + ": " + device.TargetDeviceIndex); device.ReceiveAlive(); } break; case "bye": { // {"pcmd":"bye","devidx":N} // 一定時間生存確認が無い場合に通達して以後切断。 if (null != device) { Debug.Log("[GogyoNetwork]: Received bye pcmd from " + address + ":" + port + ": " + device.TargetDeviceIndex); ProcessBye(device); } } break; default: // PeripheralDeviceに処理を委譲. if (null != device && null != device.Target) { device.Target.OnReceive(data, address, port); } else { // devidxが書かれていない通信内容は同じデバイスを登録している全員に伝える. List <PeripheralConnectedDevice> devices = FindByAddress(address, port); foreach (PeripheralConnectedDevice d in devices) { if (null != d.Target) { d.Target.OnReceive(data, address, port); } } } break; } } }