public async Task InitializeSession(TLCFIClientSession session, TLCFIClientConfig config, TLCFIClientStateManager stateManager, CancellationToken token) { if (config == null) { throw new NullReferenceException("Config is null, has SetConfig been called first?"); } try { var sessionId = await RegisterAsync(session, config, token); if (!session.State.Registered) { throw new TLCFISessionException("Registering with TLC failed"); } ApplicationRegistered?.Invoke(this, EventArgs.Empty); session.StartAliveTimers(); await GetSessionDataAsync(sessionId, session, config, stateManager, token); if (stateManager == null) { return; } await ReadFacilitiesMetaAsync(session, config, stateManager, token); Intersection inter = null; if (!config.UseIdsFromTLCForSubscription) { inter = await ReadIntersectionMetaAndSubscribeAsync(session, config, stateManager, token); } var refs = CollectAllRefs(stateManager.Facilities, inter, config); CheckMetaData(stateManager.Facilities, inter, config); await ReadAllObjectsMetaAsync(refs, session, config, stateManager, token); await SubscribeAllObjectsAsync(refs, session, stateManager, token); ApplicationConfigured?.Invoke(this, EventArgs.Empty); await SetInitialControlState(session, stateManager); _logger.Info("Client configured succesfully. Now ready to request control."); } catch (TLCFISessionException e) { _logger.Fatal(e, "Error initializing session. " + (e.Fatal ? "(FATAL!): " : ": ")); throw new TLCFISessionException("Error initializing session. " + (e.Fatal ? "(FATAL!) " : ""), e.Fatal); } }
private async Task <TLCFIClientStateManager> GetSessionDataAsync(string sessionId, TLCFIClientSession session, TLCFIClientConfig config, TLCFIClientStateManager stateManager, CancellationToken token) { _logger.Info("Obtaining session data and subscribing to session."); try { // Read meta for session var sref = new ObjectReference() { Ids = new[] { sessionId }, Type = TLCObjectType.Session }; var meta = await session.TLCProxy.ReadMetaAsync(sref, token); token.ThrowIfCancellationRequested(); if (meta == null || meta.Meta.Length != 1) { throw new InvalidMetaReceivedException("Incorrect response while reading session META. Meta received: " + meta); } // Check and store data, set state for session, and subscribe to session updates stateManager.Session = (TLCSessionBase)meta.Meta[0]; ValueChecker.CheckValidObjectId(stateManager.Session.Id); switch (config.ApplicationType) { case ApplicationType.Consumer: case ApplicationType.Provider: break; case ApplicationType.Control: if (stateManager.Session is ControlApplication ct) { // Start with Error state: either the TLC will set it to Offline, or we will in SetInitialControlState ct.ReqControlState = ControlState.Error; ct.StartCapability = config.StartCapability; ct.EndCapability = config.EndCapability; ct.ReqIntersection = config.RemoteIntersectionId; } break; default: throw new ArgumentOutOfRangeException(); } if (stateManager.Session.SessionType != config.ApplicationType) { throw new InvalidTLCObjectTypeException($"Type of Session (ApplicationType) incorrect. Expected {config.ApplicationType.ToString()}, got {stateManager.Session.SessionType.ToString()}"); } var data = await session.TLCProxy.SubscribeAsync(sref, token); token.ThrowIfCancellationRequested(); if (data == null || data.Data.Length != 1) { throw new InvalidStateReceivedException("Incorrect response while reading session STATE. State received: " + data); } ApplicationRegistered?.Invoke(this, EventArgs.Empty); _logger.Info("Succesfully got session meta and state: registered properly."); return(stateManager); } catch (JsonRpcException e) { session.State.Registered = false; _logger.LogRpcException(e); } catch (Exception e) { session.State.Registered = false; _logger.Info(e, "Register failed with non-jsonrpc error."); } return(null); }