?? protocol.c
字號(hào):
// ----------------------------------------------------------------------------// Copyright 2006-2007, Martin D. Flynn// All rights reserved// ----------------------------------------------------------------------------//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// // http://www.apache.org/licenses/LICENSE-2.0// // Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.//// ----------------------------------------------------------------------------// Description:// Server DMTP communication protocol handler// ---// Change History:// 2006/01/04 Martin D. Flynn// -Initial release// 2006/01/29 Martin D. Flynn// -Added header file "io.h"// 2006/02/12 Martin D. Flynn// -Added header "cerrors.h"// -Request GPS diagnostic info whem GPS error/failure received.// 2007/01/28 Martin D. Flynn// -Reset 'revoke speak-freely' timer each time we hear from the client.// -Maintain 'lastEventTimer' to acknowledge events in speak-freely mode// if we don't get an EOB from the client.// -Added support for a single queued 'pending' packet for transmission to// the client.// -Moved the handling of events, diagnostic packets, etc, to external// callback functions (thus making this module much more customizable for // specific applications).// ----------------------------------------------------------------------------#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <time.h>#include <sys/time.h>#include "tools/stdtypes.h"#include "tools/strtools.h"#include "tools/utctools.h"#include "tools/gpstools.h"#include "tools/io.h"#include "tools/threads.h"#include "base/props.h"#include "base/statcode.h"#include "server/server.h"#include "server/serrors.h"#include "server/cerrors.h"#include "server/packet.h"#include "server/events.h"#include "server/log.h"#include "server/protocol.h"#include "server/upload.h"// ----------------------------------------------------------------------------#define REVOKE_SPEAK_FREELY_INTERVAL HOUR_SECONDS(24) // 60L// ----------------------------------------------------------------------------static UInt32 lastEventSequence = 0L;static int lastEventSeqLen = 0;static TimerSec_t lastEventTimer = 0L;static utBool clientKeepAlive = utTrue; // utFalsestatic utBool clientSpeaksFirst = utFalse; // utTrue// ----------------------------------------------------------------------------static utBool serverNeedsMoreInfo = utFalse;/* indicate to server that we are expecting more information from the client */// When called, an end-of-block will be sent, rather than an end-of-transmissionvoid protSetNeedsMoreInfo(){ serverNeedsMoreInfo = utTrue;}// ----------------------------------------------------------------------------static utBool stopSpeakFreely = utFalse;static utBool startSpeakFreely = utFalse;static utBool isSpeakFreelyMode = utFalse;static int speakFreelyMaxEvents = -1;/* set client speakFreely mode */void protSetSpeakFreelyMode(utBool mode, int maxEvents){ if (mode) { // start speakFreely if (!isSpeakFreelyMode) { startSpeakFreely = utTrue; } speakFreelyMaxEvents = maxEvents; } else { // stop speakFreely if (isSpeakFreelyMode) { stopSpeakFreely = utTrue; } }}// ----------------------------------------------------------------------------#define PENDING_QUE_SIZE 30 // <-- will hold a maximum of (SIZE - 1) packetsstatic int pendingQueFirst = 0L;static int pendingQueLast = 0L;static Packet_t pendingQue[PENDING_QUE_SIZE];static threadMutex_t pendingMutex;#define PENDING_LOCK MUTEX_LOCK(&pendingMutex);#define PENDING_UNLOCK MUTEX_UNLOCK(&pendingMutex);utBool protAddPendingPacket(Packet_t *pkt){ if (pkt) { utBool rtn = utFalse; PENDING_LOCK { int newLast = ((pendingQueLast + 1L) < PENDING_QUE_SIZE)? (pendingQueLast + 1L) : 0L; if (newLast != pendingQueFirst) { memcpy(&pendingQue[pendingQueLast], pkt, sizeof(Packet_t)); pendingQueLast = newLast; logINFO(LOGSRC,"Pending packet set ..."); rtn = utTrue; } else { logWARNING(LOGSRC,"Pending packet queue is full ..."); rtn = utFalse; } } PENDING_UNLOCK return rtn; } else { logWARNING(LOGSRC,"Null packet specified ..."); return utFalse; }}static Packet_t *protGetPendingPacket(Packet_t *pkt){ if (pkt) { Packet_t *rtn = (Packet_t*)0; PENDING_LOCK { if (pendingQueFirst != pendingQueLast) { int newFirst = ((pendingQueFirst + 1L) < PENDING_QUE_SIZE)? (pendingQueFirst + 1L) : 0L; memcpy(pkt, &pendingQue[pendingQueFirst], sizeof(Packet_t)); pendingQueFirst = newFirst; rtn = pkt; } else { rtn = (Packet_t*)0; } } PENDING_UNLOCK return rtn; } else { return (Packet_t*)0; }}static utBool protHasPendingPackets(){ utBool rtn = utFalse; PENDING_LOCK { rtn = (pendingQueFirst != pendingQueLast)? utTrue : utFalse; } PENDING_UNLOCK return rtn;}// ----------------------------------------------------------------------------#if defined(INCLUDE_UPLOAD)static const char *pendingFileUpload = (char*)0;static const char *pendingFileClient = (char*)0;utBool protSetPendingFileUpload(const char *file, const char *cliFile){ logINFO(LOGSRC,"Pending 'File' Upload set ..."); pendingFileUpload = file; pendingFileClient = cliFile; return utTrue;}#endif// ----------------------------------------------------------------------------static char clientAccountID[MAX_ID_SIZE + 1];static char clientDeviceID[MAX_ID_SIZE + 1];const char *protGetAccountID(){ return clientAccountID;}const char *protGetDeviceID(){ return clientDeviceID;}// ----------------------------------------------------------------------------utBool protUploadPacket(const UInt8 *val, UInt8 valLen){ if (serverIsOpen()) { return serverWritePacketFmt(PKT_SERVER_FILE_UPLOAD, "%*b", (int)valLen, val); } else { return utFalse; }}// ----------------------------------------------------------------------------utBool protGetPropValue(UInt16 propKey){ if (serverIsOpen()) { return serverWritePacketFmt(PKT_SERVER_GET_PROPERTY, "%2x", (UInt32)propKey); } else { return utFalse; }}// ----------------------------------------------------------------------------utBool protSetPropBinary(UInt16 propKey, const UInt8 *val, UInt8 valLen){ if (serverIsOpen()) { //logINFO(LOGSRC,"Setting binary property value: [%d]", valLen); return serverWritePacketFmt(PKT_SERVER_SET_PROPERTY, "%2x%*b", (UInt32)propKey, (int)valLen, val); } else { return utFalse; }}utBool protSetPropString(UInt16 propKey, const UInt8 *val){ int valLen = strlen(val); return protSetPropBinary(propKey, val, valLen);}// ----------------------------------------------------------------------------static utBool _protSetPropUInt32(UInt16 propKey, UInt32 *val, int count, int blen){ if (serverIsOpen() && (count > 0) && (blen >= 1) && (blen <= 4)) { UInt32 pk = (UInt32)propKey; if (count == 1) { return serverWritePacketFmt(PKT_SERVER_SET_PROPERTY, "%2x%*x", pk, blen, (UInt32)val[0]); } else { UInt8 buf[PACKET_MAX_PAYLOAD_LENGTH]; Buffer_t bb, *dst = binBuffer(&bb, buf, sizeof(buf), BUFFER_DESTINATION); int i; for (i = 0; i < count; i++) { binBufPrintf(dst, "%*x", blen, (UInt32)val[i]); } int valLen = BUFFER_DATA_LENGTH(dst); return serverWritePacketFmt(PKT_SERVER_SET_PROPERTY, "%2x%*b", pk, valLen, buf); } } else { return utFalse; }}utBool protSetPropUInt32Arr(UInt16 propKey, UInt32 *val32, int count){ return _protSetPropUInt32(propKey, val32, count, 4);}utBool protSetPropUInt32(UInt16 propKey, UInt32 val32){ return _protSetPropUInt32(propKey, &val32, 1, 4);}utBool protSetPropUInt16Arr(UInt16 propKey, UInt16 *val, int count){ int i, m = 8; UInt32 val32[8]; for (i = 0; (i < count) && (i < m); i++) { val32[i] = (UInt32)val[i]; } return _protSetPropUInt32(propKey, val32, ((count <= m)? count : m), 2);}utBool protSetPropUInt16(UInt16 propKey, UInt16 val){ UInt32 val32 = (UInt32)val; return _protSetPropUInt32(propKey, &val32, 1, 2);}utBool protSetPropUInt8Arr(UInt16 propKey, UInt8 *val, int count){ int i, m = 8; UInt32 val32[8]; for (i = 0; (i < count) && (i < m); i++) { val32[i] = (UInt32)val[i]; } return _protSetPropUInt32(propKey, val32, ((count <= m)? count : m), 1);}utBool protSetPropUInt8(UInt16 propKey, UInt8 val){ UInt32 val32 = (UInt32)val; return _protSetPropUInt32(propKey, &val32, 1, 1);}// ----------------------------------------------------------------------------static protEventCallbackFtn_t ftnEventHandler = 0;void protocolSetEventHandler(protEventCallbackFtn_t ftn){ ftnEventHandler = ftn;}static void protocolHandleEvent(Packet_t *pkt, Event_t *ev){ if (ftnEventHandler) { (*ftnEventHandler)(pkt, ev); }}// ----------------------------------------------------------------------------static protDataCallbackFtn_t ftnPropertyHandler = 0;void protocolSetPropertyHandler(protDataCallbackFtn_t ftn){ ftnPropertyHandler = ftn;}static void protocolHandleProperty(UInt16 propKey, const UInt8 *propData, UInt16 propDataLen){ if (ftnPropertyHandler) { (*ftnPropertyHandler)(propKey, propData, propDataLen); }}// ----------------------------------------------------------------------------static protDataCallbackFtn_t ftnDiagHandler = 0;void protocolSetDiagHandler(protDataCallbackFtn_t ftn){ ftnDiagHandler = ftn;}static void protocolHandleDiag(UInt16 diagKey, const UInt8 *diagData, UInt16 diagDataLen){ if (ftnDiagHandler) { (*ftnDiagHandler)(diagKey, diagData, diagDataLen); }}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -