⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protocol.c

📁 Open DMT Client C Source code
💻 C
📖 第 1 页 / 共 5 页
字号:
                // End of transmission, query response        // Payload: maxEvents[optional], serverKey[optional]        case PKT_SERVER_EOB_DONE     : {            // flush server input buffer (useful for 'serial' transport only)            _protocolFlushInput(pv);             // The server is expecting the client to respond as soon as possible            pv->speakFreely = utFalse; // relinquish speak-freely permission            pv->speakFreelyMaxEvents = -1;            // Get max number of events to send (if specified)            Int32 eobMaxEvents = -1L;            if (srvPkt->dataLen > 0) {                int fldCnt = binScanf(srvPkt->data, (int)srvPkt->dataLen, "%1i", &eobMaxEvents);                if (fldCnt < 1) { eobMaxEvents = -1L; }            }            // Send our packets            if (!_protocolSendAllPackets(pv, TRANSPORT_DUPLEX, pv->speakBrief, (int)eobMaxEvents)) {                return utFalse; // write error            }            // Clear 'speakBrief' (we've already had our opportunity to speak).            pv->speakBrief = utFalse;            return utTrue;        }                // End of transmission, speak freely        // Payload: maxEvents[optional], serverKey[optional]        case PKT_SERVER_EOB_SPEAK_FREELY: {            // The server is NOT expecting the client to respond anytime soon            pv->speakFreely = utTrue; // 'speak-freely' permission granted            pv->speakFreelyMaxEvents = -1;            // Get max number of events to send (if specified)            Int32 eobMaxEvents = -1L;            if (srvPkt->dataLen > 0) {                int fldCnt = binScanf(srvPkt->data, (int)srvPkt->dataLen, "%1i", &eobMaxEvents);                if (fldCnt < 1) { eobMaxEvents = -1L; }                // SpeakFreely 'eobMaxEvents' is interpreted as follows:                //  0 - speak-freely, but don't send data from the 'event' queue                //  # - normal speak-freely, but send at most '#' events per ack block.                pv->speakFreelyMaxEvents = (int)eobMaxEvents;            }            // We will be sending data shortly (in the outer loop)            return utTrue;        }        // Acknowledge [optional sequence]        // Payload: sequence[optional]        case PKT_SERVER_ACK          : {            UInt32 sequence = SEQUENCE_ALL;            int fldCnt = binScanf(srvPkt->data, (int)srvPkt->dataLen, "%4x", &sequence);            if (fldCnt > 0) {                // remove sent/acknowledged events from queue up to specified sequence #                if (!_protocolAcknowledgeToSequence(pv,sequence)) {                    // ACK error                    int seqLen = (srvPkt->dataLen <= 4)? srvPkt->dataLen : 4;                    _protocolQueueError(pv,"%2x%2x%*x", (UInt32)ERROR_PACKET_ACK, (UInt32)srvPkt->hdrType, seqLen, sequence);                }            } else {                // remove all sent events from queue                _protocolAcknowledgeToSequence(pv,SEQUENCE_ALL);            }            return utTrue;        }                // Get property        // Payload: propertyKey(s)        case PKT_SERVER_GET_PROPERTY : {            Buffer_t srcBuf, *src = binBuffer(&srcBuf, srvPkt->data, srvPkt->dataLen, BUFFER_SOURCE);            if (BUFFER_DATA_LENGTH(src) >= 2) { // while?                UInt32 propKey = 0L;                int fldCnt = binScanf(BUFFER_DATA(src), (int)BUFFER_DATA_LENGTH(src), "%2u", &propKey);                binAdvanceBuffer(src, 2);                if (fldCnt > 0) {                    UInt8 *args   = BUFFER_DATA(src);                    UInt16 argLen = BUFFER_DATA_LENGTH(src);                    // queue property value packet                    Packet_t propPkt;                    PropertyError_t propErr = propGetPropertyPacket(pv->protoNdx, &propPkt, (Key_t)propKey, args, argLen);                    if (PROP_ERROR_CODE(propErr) == PROP_ERROR_OK) {                        // property packet initialized successfully                        _protocolQueuePacket(pv,&propPkt);                        // packet queueing errors are ignored (possible internal buffer overflow)                    } else                    if (PROP_ERROR_CODE(propErr) == PROP_ERROR_INVALID_KEY) {                        // unsupported property                        _protocolQueueError(pv,"%2x%2x", (UInt32)ERROR_PROPERTY_INVALID_ID, (UInt32)propKey);                        // packet queueing errors are ignored (possible internal buffer overflow)                    } else                    if (PROP_ERROR_CODE(propErr) == PROP_ERROR_WRITE_ONLY) {                        // write-only property                        _protocolQueueError(pv,"%2x%2x", (UInt32)ERROR_PROPERTY_WRITE_ONLY, (UInt32)propKey);                        // packet queueing errors are ignored (possible internal buffer overflow)                    } else                    if (PROP_ERROR_CODE(propErr) == PROP_ERROR_INVALID_LENGTH) {                        // invalid payload length                        _protocolQueueError(pv,"%2x%2x", (UInt32)ERROR_PROPERTY_INVALID_VALUE, (UInt32)propKey);                        // returned 'queue' errors are ignored (possible internal buffer overflow)                    } else                    if (PROP_ERROR_CODE(propErr) == PROP_ERROR_COMMAND_INVALID) {                        // command not supported/initialized                        // this will not occur, since commands are write-only                        _protocolQueueError(pv,"%2x%2x", (UInt32)ERROR_COMMAND_INVALID, (UInt32)propKey);                        // packet queueing errors are ignored (possible internal buffer overflow)                    } else                    if (PROP_ERROR_CODE(propErr) == PROP_ERROR_COMMAND_ERROR) {                        // command error                        // this will not occur, since commands are write-only                        UInt16 errCode = (UInt16)PROP_ERROR_ARG(propErr);                        _protocolQueueError(pv,"%2x%2x%2x", (UInt32)ERROR_COMMAND_ERROR, (UInt32)propKey, (UInt32)errCode);                        // packet queueing errors are ignored (possible internal buffer overflow)                    } else {                        // internal error                        // send error back to server: ERROR_PROPERTY_UNKNOWN_ERROR                        _protocolQueueError(pv,"%2x%2x", (UInt32)ERROR_PROPERTY_UNKNOWN_ERROR, (UInt32)propKey);                        // packet queueing errors are ignored (possible internal buffer overflow)                    }                } else {                    // no property specified                    _protocolQueueError(pv,"%2x%2x", (UInt32)ERROR_PACKET_PAYLOAD, (UInt32)srvPkt->hdrType);                    // packet queueing errors are ignored (possible internal buffer overflow)                }            }            return utTrue;        }                // Set property        // Payload: propertyKey, propertyValue[optional]        case PKT_SERVER_SET_PROPERTY : {             UInt32 propKey = 0L;            int valDataLen = (srvPkt->dataLen > 2)? (int)(srvPkt->dataLen - 2) : 0;            UInt8 valData[PACKET_MAX_ENCODED_LENGTH];             int fldCnt = binScanf(srvPkt->data, (int)srvPkt->dataLen, "%2x%*b", &propKey, valDataLen, valData);            if (fldCnt >= 1) {                // set property value                // TODO: If property is a 'Command', it would be very handy to be able to                 // let the property manager where to queue the returned data (specifically                 // the primary/secondary protocol)                PropertyError_t propErr = propSetValueCmd(pv->protoNdx, (Key_t)propKey, valData, valDataLen); // ok as-is                if (PROP_ERROR_CODE(propErr) == PROP_ERROR_OK) {                    // property set successfully                    // no packet response                } else                if (PROP_ERROR_CODE(propErr) == PROP_ERROR_INVALID_KEY) {                    // unsupported property key                    _protocolQueueError(pv,"%2x%2x", (UInt32)ERROR_PROPERTY_INVALID_ID, (UInt32)propKey);                    // returned errors are ignored (possible internal buffer overflow)                } else                if (PROP_ERROR_CODE(propErr) == PROP_ERROR_INVALID_TYPE) {                    // internal error, invalid type                    _protocolQueueError(pv,"%2x%2x", (UInt32)ERROR_PROPERTY_UNKNOWN_ERROR, (UInt32)propKey);                    // returned errors are ignored (possible internal buffer overflow)                } else                if (PROP_ERROR_CODE(propErr) == PROP_ERROR_INVALID_LENGTH) {                    // invalid payload length                    _protocolQueueError(pv,"%2x%2x", (UInt32)ERROR_PROPERTY_INVALID_VALUE, (UInt32)propKey);                    // returned errors are ignored (possible internal buffer overflow)                } else                if (PROP_ERROR_CODE(propErr) == PROP_ERROR_READ_ONLY) {                    // read-only property                    _protocolQueueError(pv,"%2x%2x", (UInt32)ERROR_PROPERTY_READ_ONLY, (UInt32)propKey);                    // returned errors are ignored (possible internal buffer overflow)                } else                if (PROP_ERROR_CODE(propErr) == PROP_ERROR_COMMAND_INVALID) {                    // command not supported/initialized                    _protocolQueueError(pv,"%2x%2x", (UInt32)ERROR_COMMAND_INVALID, (UInt32)propKey);                    // returned errors are ignored (possible internal buffer overflow)                } else                if (PROP_ERROR_CODE(propErr) == PROP_ERROR_COMMAND_ERROR) {                    // command not supported/initialized, or possibly COMMAND_OK_ACK                    UInt16 errCode = (UInt16)PROP_ERROR_ARG(propErr);                    _protocolQueueError(pv,"%2x%2x%2x", (UInt32)ERROR_COMMAND_ERROR, (UInt32)propKey, (UInt32)errCode);                    // returned errors are ignored (possible internal buffer overflow)                } else {                    // likely internal error                    _protocolQueueError(pv,"%2x%2x", (UInt32)ERROR_PROPERTY_UNKNOWN_ERROR, (UInt32)propKey);                    // returned errors are ignored (possible internal buffer overflow)                }            } else {                // no property specified                _protocolQueueError(pv,"%2x%2x", (UInt32)ERROR_PACKET_PAYLOAD, (UInt32)srvPkt->hdrType);                // returned errors are ignored (possible internal buffer overflow)            }            return utTrue;        }        // File upload        case PKT_SERVER_FILE_UPLOAD  : { #if defined(ENABLE_UPLOAD)            uploadProcessRecord(pv->protoNdx, srvPkt->data, (int)srvPkt->dataLen);            // this already sends error/ack packets#else            _protocolQueueError(pv,"%2x%2x", (UInt32)ERROR_PACKET_TYPE, (UInt32)srvPkt->hdrType);            // returned errors are ignored (possible internal buffer overflow)#endif            return utTrue;        }                // NAK/Error codes        // Payload: errorCode, packetHeader, packetType, extraData        case PKT_SERVER_ERROR        : {             UInt32 errCode = 0L, pktHdrType = 0L;            int valDataLen = (srvPkt->dataLen > 2)? (int)(srvPkt->dataLen - 2) : 0;            UInt8 valData[PACKET_MAX_ENCODED_LENGTH];             int fldCnt = binScanf(srvPkt->data, (int)srvPkt->dataLen, "%2x%2x%*b", &errCode, &pktHdrType, valDataLen, valData);            if (fldCnt >= 1) {                // 'errCode' contains the Error Code                // 'pktHdr'  contains the error packet header                // 'pktTyp'  containt the error packet type                // 'valData' contains any additional data                utBool ok = _protocolHandleErrorCode(pv, (UInt16)errCode, (ClientPacketType_t)pktHdrType, valData, valDataLen);                if (!ok) {                    return utFalse; // critical error determined by error code                }            } else {                // no error specified                _protocolQueueError(pv,"%2x%2x", (UInt32)ERROR_PACKET_PAYLOAD, (UInt32)srvPkt->hdrType);                // returned errors are ignored (possible internal buffer overflow)            }            return utTrue;        }                // End transmission (socket will be closed)        // Payload: none        case PKT_SERVER_EOT          : {             // return false to close communications            return utFalse; // server is closing the connection        }                // Invalid packet type        default: {            _protocolQueueError(pv,"%2x%2x", (UInt32)ERROR_PACKET_TYPE, (UInt32)srvPkt->hdrType);            // returned errors are ignored (possible internal buffer overflow)            return utTrue;        }            }    }// ----------------------------------------------------------------------------// This function checks to see if it is time to make a connection to the DMT service// provider, and what type of connection to make.  The time of the last connection// and the number of connections made in the last hour are considered.static TransportType_t _getTransportType(ProtocolVars_t *pv){        /* secondary protocol */    if (!pv->isPrimary) { // duplex transport for non-primary transport        // Assume the secondary protocol supports duplex        // - Highest event priority is PRIORITY_NONE (no events are sent to the secondary protocol)        // - Never over duplex quota        return TRANSPORT_DUPLEX;    }    /* first check absolute minimum delay between connections */    if (!acctAbsoluteDelayExpired()) {        // absolute minimum delay interval has not expired        //logINFO(LOGSRC,"Absolute minimum delay interval has not expired");        return TRANSPORT_NONE;    }        /* check specific event priority */    TransportType_t xportType = TRANSPORT_NONE;    PacketPriority_t evPri = _protocolGetHighestPriority(pv);    switch (evPri) {        // no events, time for 'checkup'?        case PRIORITY_NONE:             if (!acctUnderTotalQuota()) {                // over Total quota                xportType = TRANSPORT_NONE;            } else            if (!acctMaxIntervalExpired()) {                // MAX interval has not expired                xportType = TRANSPORT_NONE;            } else            if (acctUnderDuplexQuota()) {                // under Total/Duplex quota and MAX interval expired, time for Duplex checkup                //logDEBUG(LOGSRC,"_getTransportType: NONE/DUPLEX ...");                xportType = TRANSPORT_DUPLEX;            } else {                // over Duplex quota                xportType = TRANSPORT_NONE;            }            break;        // low priority events        case PRIORITY_LOW:             if (!acctUnderTotalQuota()) {                // over Total quota, no sending                xportType = TRANSPORT_NONE;            } else            if (!acctMinIntervalExpired()) {                // min interval has not expired, no sending                xportType = TRANSPORT_NONE;            } else            if (acctSupportsSimplex()) {                // under Total quota, min interval expired, send Simplex                //logDEBUG(LOGSRC,"_getTransportType: 1 LOW/SIMPLEX ...");                xportType = TRANSPORT_SIMPLEX;            } else            if (acctUnderDuplexQuota()) {                // under Total/Duplex quota and min interval expired, Simplex not supported, send Duplex        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -