gt:             if ((gateReq != null) && (!socketIsClosed)) {
context: /*
   * Copyright (c) 2015 CableLabs and others.  All rights reserved.
   *
   * This program and the accompanying materials are made available under the
   * terms of the Eclipse Public License v1.0 which accompanies this distribution,
   * and is available at http://www.eclipse.org/legal/epl-v10.html
   */
  package org.opendaylight.controller.packetcable.provider;
  
  import com.google.common.collect.Maps;
  import java.net.InetAddress;
  import java.util.Map;
  import javax.annotation.concurrent.ThreadSafe;
  import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
  import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
  import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ServiceClassName;
  import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ServiceFlowDirection;
  import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.ccaps.Ccap;
  import org.opendaylight.yang.gen.v1.urn.packetcable.rev170224.pcmm.qos.gates.apps.app.subscribers.subscriber.gates.Gate;
  import org.pcmm.PCMMPdpAgent;
  import org.pcmm.PCMMPdpDataProcess;
  import org.pcmm.PCMMPdpMsgSender;
  import org.pcmm.gates.IGateState;
  import org.pcmm.gates.ITransactionID;
  import org.pcmm.gates.impl.PCMMGateReq;
  import org.pcmm.gates.impl.TransactionID;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.umu.cops.prpdp.COPSPdpException;
  import org.umu.cops.stack.COPSError;
  import org.umu.cops.stack.COPSError.ErrorTypes;
  import java.nio.ByteBuffer;
  
  
  /**
   * Class responsible for managing the gates for a single CCAP.
   */
  @ThreadSafe
  public class PCMMService {
      private final Logger logger = LoggerFactory.getLogger(PCMMService.class);
  
      private final Ccap ccap;
      private final IpAddress ipAddr;
      private final PortNumber portNum;
      protected final CcapClient ccapClient;
      protected Map<String, PCMMGateReq> gateRequests = Maps.newConcurrentMap();
  
      private final short clientType;
  
      public PCMMService(final short clientType, final Ccap ccap) {
          this.clientType = clientType;
          this.ccap = ccap;
          ipAddr = ccap.getConnection().getIpAddress();
          portNum = ccap.getConnection().getPort();
  
          ccapClient = new CcapClient(ipAddr, portNum);
          logger.info("Attempting to add CCAP with ID {} @ {}:{}", ccap.getCcapId(), ipAddr.getIpv4Address().getValue(),
                  portNum.getValue());
      }
  
      public void disconect() {
          ccapClient.disconnect();
      }
  
      // TODO - try and change the return to something other than a String to be parsed to determine success
      public String addCcap() {
          ccapClient.connect();
          if (ccapClient.isConnected) {
              logger.info("Connected to CCAP with ID - " + ccap.getCcapId());
              return String
                      .format("200 OK - CCAP %s connected @ %s:%d", ccap.getCcapId(), ipAddr.getIpv4Address().getValue(),
                              portNum.getValue());
          } else {
              return String.format("404 Not Found - CCAP %s failed to connect @ %s:%d - %s", ccap.getCcapId(),
                      ipAddr.getIpv4Address().getValue(), portNum.getValue(), ccapClient.errMessage);
          }
      }
  
      public class GateSendStatus {
          private boolean didSucceed = false;
          private String message = "";
          private String copsGateId = "";
          private String copsGateState = "";
          private String copsGateStateReason = "";
          private String copsGateTimeInfo = "";
          private String copsGateUsageInfo = "";
  
          public boolean didSucceed() {
              return didSucceed;
          }
  
          void setDidSucceed(final boolean didSucceed) {
              this.didSucceed = didSucceed;
          }
  
          public String getMessage() {
              return message;
          }
  
          void setMessage(final String message) {
              this.message = message;
          }
  
          public String getCopsGateId() {
              return copsGateId;
          }
  
          void setCopsGateId(final String copsGateId) {
              this.copsGateId = copsGateId;
          }
  
          public String getCopsGateState() {
              return copsGateState;
          }
          void setCopsGateState(final String copsGateState) {
              this.copsGateState = copsGateState;
          }
  
          public String getCopsGateStateReason() {
              return copsGateStateReason;
          }
          void setCopsGateStateReason(final String copsGateStateReason) {
              this.copsGateStateReason = copsGateStateReason;
          }
  
          public String getCopsGateTimeInfo() {
              return copsGateTimeInfo;
          }
          void setCopsGateTimeInfo(final String copsGateTimeInfo) {
              this.copsGateTimeInfo = copsGateTimeInfo;
          }
  
          public String getCopsGateUsageInfo() {
              return copsGateUsageInfo;
          }
          void setCopsGateUsageInfo(final String copsGateUsageInfo) {
              this.copsGateUsageInfo = copsGateUsageInfo;
          }
      }
  
      private static long getUnsignedInt(int x) {
          return x & 0xFFFFFFFFL;
      }
  
      public GateSendStatus sendGateSet(final String gatePathStr, final InetAddress subId, final Gate qosGate) {
  
          GateSendStatus status = new GateSendStatus();
  
          logger.info("Sending gate to CCAP with ID - " + ccap.getCcapId());
  
          // assemble the gate request for this subId
          final PCMMGateReqBuilder gateBuilder = new PCMMGateReqBuilder();
          gateBuilder.setAmId(ccap.getAmId());
          gateBuilder.setSubscriberId(subId);
          gateBuilder.setGateSpec(qosGate.getGateSpec());
          gateBuilder.setTrafficProfile(qosGate.getTrafficProfile());
          gateBuilder.setClassifiers(qosGate.getClassifiers().getClassifierContainer());
  
          if (qosGate.getCopsGateId() != null) {
              long lgate = Long.parseLong(qosGate.getCopsGateId());
              gateBuilder.setGateId((int)lgate);
          }
          
          logger.debug("PCMMService: sendGateSet(): formatting gate");
          
          // assemble the final gate request
          final PCMMGateReq gateReq = gateBuilder.build();
  
          if (gateRequests.get(gatePathStr) == null) {
              // and remember it
              gateRequests.put(gatePathStr, gateReq);
              // and send it to the CCAP
              ccapClient.sendGateSet(gateReq);
              // and wait for the COPS response to complete processing gate request
              try {
                  // TODO - see PCMMPdpReqStateMan#processReport() gate.notify(). Should determine a better means to
                  // TODO - handle this synchronization.
                  // TODO - if not changing this, may want to make this timeout configurable
                  synchronized (gateReq) {
                      logger.info("Waiting 5000ms for gate request to be updated");
                      gateReq.wait(5000);
                      logger.debug("Gate request error - " + gateReq.getError());
                      logger.debug("Gate request ID - " + gateReq.getGateID());
                  }
              } catch (Exception e) {
                  logger.error("PCMMService: sendGateSet(): gate response timeout exceeded for " + gatePathStr + '/' + gateReq,
                               e);
                  status.setDidSucceed(false);
                  status.setMessage(String.format("408 Request Timeout - gate response timeout exceeded for %s/%s", ccap.getCcapId(),
                                                  gatePathStr));
                  return status;
              }
  
              if (gateReq.getError() != null) {
                  gateRequests.remove(gatePathStr);
                  status.setDidSucceed(false);
                  status.setMessage(String.format("404 Not Found - sendGateSet for %s/%s returned error - %s", ccap.getCcapId(),
                                                  gatePathStr, gateReq.getError().toString()));
  
                  logger.error("PCMMService: sendGateSet(): returned error: {}", gateReq.getError().toString());
              } else {
                  if (gateReq.getGateID() != null) {
                      status.setDidSucceed(true);
                      status.setCopsGateId(String.format("%d", getUnsignedInt(gateReq.getGateID().getGateID())));
                      status.setMessage(String.format("200 OK - sendGateSet for %s/%s returned GateId %d",
                                                      ccap.getCcapId(), gatePathStr, getUnsignedInt(gateReq.getGateID().getGateID())) );
                      logger.info(String.format("PCMMService: sendGateSet(): returned GateId %d: ",
                                                getUnsignedInt(gateReq.getGateID().getGateID())));
                  } else {
                      status.setDidSucceed(false);
                      status.setMessage(
                                        String.format("404 Not Found - sendGateSet for %s/%s no gateId returned", ccap.getCcapId(),
                                                      gatePathStr));
  
                      logger.info("PCMMService: sendGateSet(): no gateId returned:");
                  }
              }
          } else {
              logger.info("PCMMService: sendGateSet(): no gateId returned:");
              status.setMessage(String.format("404 Not Found - sendGateSet for %s/%s already exists", ccap.getCcapId(), gatePathStr));
          }
  
          return status;
      }
  
      public Boolean sendGateDelete(final String gatePathStr) {
          logger.info("sendGateDelete() - " + ccap);
          // recover the original gate request
          final PCMMGateReq gateReq = gateRequests.remove(gatePathStr);
          if (gateReq != null) {
              ccapClient.sendGateDelete(gateReq);
              // and wait for the response to complete
              try {
                  // TODO - see PCMMPdpReqStateMan#processReport() gate.notify(). Should determine a better means to
                  // TODO - handle this synchronization.
                  synchronized (gateReq) {
                      gateReq.wait(1000);
                  }
              } catch (InterruptedException e) {
                  logger.error("PCMMService: sendGateDelete(): gate response timeout exceeded for {}/{}", gatePathStr,
                          gateReq);
              }
              if (gateReq.getError() != null) {
                  logger.warn("PCMMService: sendGateDelete(): returned error: {}", gateReq.getError().toString());
                  return false;
              } else {
                  if (gateReq.getGateID() != null) {
                      logger.info(String.format("PCMMService: sendGateDelete(): deleted GateId %d: ",
                                                getUnsignedInt(gateReq.getGateID().getGateID())));
                  } else {
                      logger.error("PCMMService: sendGateDelete(): deleted but no gateId returned");
                  }
                  return true;
              }
          } else {
              logger.warn("Attempt to delete non-existent gate with path - " + gatePathStr);
              return false;
          	}
          }
  
      	public Boolean getPcmmPdpSocket() {
      		try {
      			return ccapClient.pcmmPdp.getSocket().isClosed();
      		} catch (Exception e) {
      			logger.error("getPcmmPdpSocket: {} FAILED: {}", ccapClient, e.getMessage());
      			return true;
      		}
      	}
  
      	public Boolean getPcmmCcapClientIsConnected() {
      		try {
      			return ccapClient.isConnected;
      		} catch (Exception e) {
      			logger.error("getPcmmCcapClientIsConnected: {} FAILED: {}", ccapClient, e.getMessage());
      			return false;
      		}
      	}
  
      	public String getPcmmCcapClientConnectErrMsg() {
      		try {
      			return ccapClient.errMessage;
      		} catch (Exception e) {
      			logger.error("getPcmmCcapClientIsConnected: {} FAILED: {}", ccapClient, e.getMessage());
      			return e.getMessage();
      		}
      	}
  
          //new gate-info method
      	public GateSendStatus sendGateInfo(final String gatePathStr) {
  
      		logger.info("sendGateInfo() - " + ccap);
  
      		GateSendStatus status = new GateSendStatus();
  
              // recover the original gate request
              final PCMMGateReq gateReq = gateRequests.get(gatePathStr);
  
              // is the ccap socket open?
              final Boolean socketIsClosed = getPcmmPdpSocket();
  
  