Esempio n. 1
0
/**
 * Prints command queue - convenience and bugfixing.
 */
void ClientSonyVISCAoverIP::printCommandQueue(uint8_t cam) {
  for (uint8_t a = 1; a < SONYVISCAIP_comBufSize; a++) { // Start from the next non-sent command
    Serial << a << ": idx:" << ((_applicationCommandBufferCurrentIndex[cam - 1] + a) % SONYVISCAIP_comBufSize) << ": ";
    for (uint8_t b = 0; b < 15; b++) {
      Serial << _HEXPADL(_applicationCommandBuffer[cam - 1][(_applicationCommandBufferCurrentIndex[cam - 1] + a) % SONYVISCAIP_comBufSize][b], 2, "0") << " ";
    }
    Serial << "\n";

    if ((_applicationCommandBufferCurrentIndex[cam - 1] + a) % SONYVISCAIP_comBufSize == _applicationCommandBufferLastPositionAdded[cam - 1]) {
      break;
    }
  }
}
bool ClientAJAKumoTCP::receiveData() {
    _inputPos = 0;
    memset(_inputBuffer, 0, ClientAJAKumoTCP_INPUTBUFFER_SIZE);
    while(_client.available() && _inputPos < ClientAJAKumoTCP_INPUTBUFFER_SIZE) {
        char c = _client.read();
        _inputBuffer[_inputPos++] = c;
        if(_serialOutput > 1)
            Serial << _HEXPADL(c, 2, "0") << ":";

        if(c == 0x04) {
            if(_serialOutput > 1) {
                Serial << " : " << (char*)_inputBuffer << "\n";
            }

            parseIncoming(_inputBuffer, _inputPos);
            _inputPos = 0;
            return true;
        }
    }
    return false;
}
void ClientAJAKumoTCP::transmitPacket(char* data) {
    uint8_t len = strlen(data);
    uint8_t *_buffer = (uint8_t*)malloc(6 + len);
    // Prepare packet
    _buffer[0] = 0x01; // SOH
    _buffer[1] = 'N'; // Protocol ID
    _buffer[2] = toASCII(_sessionID & 0xF);

    for(uint8_t i = 0; i < len; i++) {
        if(data[i] == ',') {
            _buffer[3+i] = 0x09; // HT
        } else {
            _buffer[3+i] = data[i];
        }
    }

    uint16_t checksum = calculateChecksum(_buffer, 3+len);

    _buffer[3+len] = checksum >> 8;
    _buffer[4+len] = checksum & 0xFF;

    _buffer[5+len] = 0x04; // EOT

    if(_client.connected()) {
        if(_serialOutput > 1) {
            for(uint8_t j=0; j<6+len; j++) {
                Serial << _HEXPADL(_buffer[j], 2, "0") << ":";
            }
            Serial << "\n";
        }

        _client.write(_buffer, 6 + len);
    }

    free(_buffer);
}
Esempio n. 4
0
/**
 * Keeps connection to the cameras alive: Reads UDP incoming and empties/processes the outgoing command queue
 * Therefore: Call this in the loop() function and make sure it gets called multiple times a second, including after sending commands.
 */
void ClientSonyVISCAoverIP::runLoop(uint16_t delayTime) {

  unsigned long enterTime = millis();
  do {

    // Reading incoming UDP data on port:
    while (true) { // Iterate until UDP buffer is empty
      uint16_t packetSize = _Udp.parsePacket();

      if (_Udp.available()) {
        IPAddress remote = _Udp.remoteIP();
        uint8_t cam = remote[3] - forthByteBase; // Select the cam from the IP address.

        if (camNumOK(cam)) {           // valid range for VISCA
          _Udp.read(_packetBuffer, 8); // Read header
          uint16_t payloadType = word(_packetBuffer[0], _packetBuffer[1]);
          uint16_t packetLength = word(_packetBuffer[2], _packetBuffer[3]);
          uint16_t sequenceNumber = word(_packetBuffer[6], _packetBuffer[7]); // Actually, this is probably a 32 bit unsigned long...
          if (packetSize == packetLength + 8) {                               // Just to make sure these are equal, they should be!

            if (_serialOutput & 0x80) {
              Serial << "Incoming Packet from cam #" << cam << " (" << packetLength << " bytes): 0x" << _HEXPADL(payloadType, 4, "0") << ": ";
              for (uint8_t a = 4; a < 8; a++) {
                Serial << _HEXPADL(_packetBuffer[a], 2, "0") << " ";
              }
              Serial << " / ";
            }

            // Read the VISCA packet itself:
            _Udp.read(_packetBuffer, SONYVISCAIP_packetBufferLength);

            if (_serialOutput & 0x80) {
              for (uint8_t a = 0; a < packetLength; a++) {
                Serial << _HEXPADL(_packetBuffer[a], 2, "0") << " ";
              }
              Serial << ": ";
            }

            if (!_isConnected[cam - 1]) {                                                   // If not connected, look for reply to reset counter package
              if (payloadType == 0x0201 && packetLength == 1 && _packetBuffer[0] == 0x01) { // Response to sequence number "RESET" connect package
                _isConnected[cam - 1] = true;
                if (_serialOutput & 0x80) {
                  Serial << F("Connected to VISCA camera #") << cam << "\n";
                }
              }
            } else {
              _lastContact[cam - 1] = millis();
              _pushedStateUpdate[cam - 1] = false;
              if (_camLastTX[cam - 1] > 0) { // Waiting for response
                // if (_localPacketIdCounter[cam - 1] == sequenceNumber) {	// the returned sequence number is a reference to the sequence number we sent to the camera - but notice that an ack and complete package will refer to the same number. At the moment I see no need to track the package number - we just look for acks and ignores "completes"
                if (payloadType == 0x0111 && _packetBuffer[0] == 0x90) {
                  if (_applicationCommandBuffer[cam - 1][_applicationCommandBufferCurrentIndex[cam - 1]][0] == 0x01 && packetLength == 3 && (_packetBuffer[1] & 0xF0) == 0x40) { // an ack for a command
                    if (_serialOutput & 0x80) {
                      Serial << "ACK in " << (millis() - _camLastTX[cam - 1]) << "ms\n";
                    }
                    _camLastTX[cam - 1] = 0;
                  }
                  if (_applicationCommandBuffer[cam - 1][_applicationCommandBufferCurrentIndex[cam - 1]][0] == 0x01 && packetLength == 4 && (_packetBuffer[1] & 0xF0) == 0x60) { // an error for a command
                    if (_serialOutput) {
                      Serial << "ERROR in " << (millis() - _camLastTX[cam - 1]) << "ms\n";
                    }
                    _camLastTX[cam - 1] = 0;
                  }
                  if (_applicationCommandBuffer[cam - 1][_applicationCommandBufferCurrentIndex[cam - 1]][0] == 0x09 && (_packetBuffer[1] & 0xF0) == 0x50) { // a inquery answer
                    if (_serialOutput & 0x80) {
                      Serial << "INQUERY ANS in " << (millis() - _camLastTX[cam - 1]) << "ms\n";
                    }
                    _camLastTX[cam - 1] = 0;
                    parsePacketBufferInqueryData(cam);
                  }
                }
              }
            }

            if (_serialOutput & 0x80) {
              Serial << "\n";
            }
          } else {
            //#if SONYVISCAIP_debug
            if (_serialOutput & 0x80) {
              Serial.print(F("ERROR: Packet size mismatch: "));
              Serial.print(packetSize, DEC);
              Serial.print(F(" != "));
              Serial.println(packetLength, DEC);
            }
            //#endif
            // Flushing larger packets
            while (_Udp.available()) {
              _Udp.read(_packetBuffer, SONYVISCAIP_packetBufferLength);
            }
          }
        } else {
          Serial << "ERROR: Cam number " << cam << " out of range!\n";
        }
      } else
        break;
    }

    // Send a command from buffer to cameras:
    for (uint8_t cam = 1; cam <= SONYVISCAIP_cams; cam++) {
      sendCommand(cam);
    }

    // If connection is gone anyway, try to reconnect:
    for (uint8_t cam = 1; cam <= SONYVISCAIP_cams; cam++) {
      if (_camOnline[cam - 1]) {
        if (hasTimedOut(_lastContact[cam - 1], 400) && _applicationCommandBufferLastPositionAdded[cam - 1] == _applicationCommandBufferCurrentIndex[cam - 1]) { // Send a "get state update" when nothing else happens (output buffer is empty)
          // if (_serialOutput)
          //             Serial.println(F("pushNextStateUpdate()"));
          pushNextStateUpdate(cam);
        } else if (hasTimedOut(_lastContact[cam - 1], 1000 + 2000)) { // Allow a get state update 2000 ms to register
          if (_serialOutput)
            Serial.println(F("Connection to Camera has timed out - reconnecting!"));
          connect(cam);
        }
      }
    }
  } while (delayTime > 0 && !hasTimedOut(enterTime, delayTime));
}