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

📄 gprs.c

📁 Open DMT Client C Source code
💻 C
📖 第 1 页 / 共 4 页
字号:
// ----------------------------------------------------------------------------// 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://  GPRS data transport.// Notes://  - This implementation supports UDP/TCP communications with a DMTP server//  and was designed to work with the BlueTree M2M Express wireless GPRS modem//  (which is really a Wavecom modem internally and thus may work with any //  Wavecom modem, but no other modem has been tested).// ---// Change History://  2006/01/23  Martin D. Flynn//     -Initial release//  2007/01/28  Martin D. Flynn//     -Initial support for Window CE (not yet fully functional).  On most//      Windows CE platforms this module may not be neccessary as the Windows CE//      environment may already handle GPRS/CDMA connections, in which case the//      'socket' transport media may be used.// ----------------------------------------------------------------------------#include "stdafx.h" // TARGET_WINCE#include "custom/defaults.h"// ----------------------------------------------------------------------------#include <stdio.h>#include <string.h>//#include <unistd.h>//#include <fcntl.h>#include <ctype.h>//#include <errno.h>//#include <termios.h>//#include <sys/select.h>//#include <time.h>#include <stdlib.h>//#include <pthread.h>#include "custom/log.h"#include "custom/transport/gprs.h"#include "tools/stdtypes.h"#include "tools/strtools.h"#include "tools/bintools.h"#include "tools/utctools.h"#include "tools/comport.h"#include "tools/buffer.h"#include "tools/threads.h"#include "base/props.h"#include "base/propman.h"#include "base/packet.h"// ----------------------------------------------------------------------------// Note: This implementation was tested to work with the Following modem(s)://  - BlueTree M2M Express GPRS (internal WaveCom modem)// ----------------------------------------------------------------------------#define DNS_NULL                    "0.0.0.0"#define MODEM_SPEED_BPS             BPS_115200      // default speedvoid blueInitialize();void blueResetConnection();const char *blueGetDataHost();Int16 blueGetDataPort();const char *blueGetDNS(int ndx);const char *blueGetApnName();const char *blueGetApnServer();const char *blueGetApnUser();const char *blueGetApnPassword();utBool blueIsOpen();utBool blueOpenCom();void blueCloseCom();int blueConnect();utBool blueOpenTCPSocket();utBool blueIsTCPSocketOpen();utBool blueCloseSocket();int blueWrite(const char *buf, int bufLen);int blueWriteString(const char *msg);int blueWriteStringFmt(const char *fmt, ...);int blueRead(char *resp, int respLen, long timeoutMS);int blueReadString(char *resp, int respLen, long timeoutMS);utBool blueSendDatagram(char *buf, int bufLen);utBool bluePing(const char *server);// ----------------------------------------------------------------------------/* transport structure */typedef struct {    TransportType_t             type;    utBool                      isOpen;    // add whatever is needed to provide platform specific transport requirements} GprsTransport_t;static GprsTransport_t          gprsXport;// ----------------------------------------------------------------------------static TransportFtns_t          gprsXportFtns = { MEDIA_GPRS, "XportGPRS" };// The size of the datagram buffer is arbitrary, however the amount of // data transmitted in a single datagram should not be larger than the MTU// to avoid possible fragmentation which could result in a higher possibility// of data loss.static UInt8                    gprsDatagramData[2000];static Buffer_t                 gprsDatagramBuffer;// ----------------------------------------------------------------------------static const char *gprs_transportTypeName(TransportType_t type){    switch (type) {        case TRANSPORT_NONE     : return "None";        case TRANSPORT_SIMPLEX  : return "Simplex";        case TRANSPORT_DUPLEX   : return "Duplex";        default                 : return "Unknown";    }}// ----------------------------------------------------------------------------/* flush input buffer */static void gprs_transportReadFlush(){    // NO-OP}/* return true if transport is open */static utBool gprs_transportIsOpen(){    // this may be called by threads other than the protocol thread.    return gprsXport.isOpen;}/* close transport */static utBool gprs_transportClose(utBool sendUDP){    if (gprsXport.isOpen) {        logDEBUG(LOGSRC,"%s Transport close ...\n\n", gprs_transportTypeName(gprsXport.type));        utBool rtn = utTrue;        /* check for datagram transmission */        if (sendUDP && (gprsXport.type == TRANSPORT_SIMPLEX)) {            // transmit queued datagram            Buffer_t *bf = &gprsDatagramBuffer;            UInt8 *data = BUFFER_PTR(bf);            int dataLen = BUFFER_DATA_LENGTH(bf);            utBool ok = blueSendDatagram((char*)data, dataLen);            rtn = ok;        }        /* transport is closed */        gprsXport.type   = TRANSPORT_NONE;        gprsXport.isOpen = utFalse;                /* reset buffers */        binResetBuffer(&gprsDatagramBuffer);                return rtn;            } else {                /* wasn't open */        return utFalse;            }}/* open transport */static utBool gprs_transportOpen(TransportType_t type){        /* close, if already open */    if (gprsXport.isOpen) {        // it shouldn't already be open        logWARNING(LOGSRC,"Transport seems to still be open!");        gprs_transportClose(utFalse);    }    /* establish ISP connection */    // we stay here until we can connect (or until timeout)    UInt32 connectTimoutSec = MINUTE_SECONDS(5);    TimerSec_t connectErrorTimer = utcGetTimer();    while (utTrue) {        int err = blueConnect();        if (err > 0) {            // success            break;        } else        if (err < 0) {            // critical error (unable to open serial port)            return utFalse;        } else        if (utcIsTimerExpired(connectErrorTimer,connectTimoutSec)) {            return utFalse;        }        logWARNING(LOGSRC,"Retrying connect ...");        threadSleepMS(5000L);    }        /* open TCP socket */    if (type == TRANSPORT_DUPLEX) {        // Duplex        if (blueOpenTCPSocket()) {            // socket is ready writing/reading            gprsXport.type = type;            gprsXport.isOpen = utTrue;            // fall through to 'true' return below        } else {            // If we can't open the socket, then the connection is suspect.            // close and reopen connection            logINFO(LOGSRC,"Unable to open socket");            blueResetConnection();            threadSleepMS(1000L);            return utFalse;        }    } else {        // Simplex        gprsXport.type = type;        gprsXport.isOpen = utTrue;        // fall through to 'true' return below    }        /* reset buffers and return success */    binResetBuffer(&gprsDatagramBuffer);    logDEBUG(LOGSRC,"Openned %s Transport ...\n", gprs_transportTypeName(type));    return gprsXport.isOpen;    }// ----------------------------------------------------------------------------static int _transportRead(UInt8 *buf, int bufLen){        /* transport not open? */    if (!gprsXport.isOpen) {        logERROR(LOGSRC,"Transport is not open");        return -1;    }    /* cannot read when connecting via Simplex */    if (gprsXport.type == TRANSPORT_SIMPLEX) {        logERROR(LOGSRC,"Cannot read from Simplex transport");        return -1;    }        /* no data was requested */    if (bufLen == 0) {        return 0;    }        /* return bytes read */    int readLen = 0;    readLen = blueRead((char*)buf, bufLen, 5000L);    return readLen;    }/* read packet from transport */static int gprs_transportReadPacket(UInt8 *buf, int bufLen){    UInt8 *b = buf;    int readLen, len;        /* check minimum 'bufLen' */    if (bufLen < PACKET_HEADER_LENGTH) {        logERROR(LOGSRC,"Read overflow");        return -1;    }        /* read header */    // This will read the header/type/length of a binary encoded packet, or    // the '$' and 2 ASCII hex digits of an ASCII encoded packet.    len = _transportRead(b, PACKET_HEADER_LENGTH);    if (len < 0) {        logERROR(LOGSRC,"Read error");        return -1;    } else    if (len == 0) {        logERROR(LOGSRC,"Timeout");        return 0;    }    /* make sure entire header has been read */    if (len < PACKET_HEADER_LENGTH) {        // partial packet read (just close socket)        logERROR(LOGSRC,"Read error [len=%d, expected %d]", len, PACKET_HEADER_LENGTH);        return -1;    }    b += PACKET_HEADER_LENGTH;        /* read payload */    if (buf[0] == PACKET_ASCII_ENCODING_CHAR) {        // ASCII encoded, read until '\r'        for (; (b - buf) < bufLen; b++) {            len = _transportRead(b, 1);            if (len < 0) {                logERROR(LOGSRC,"Read error");                return -1;            } else            if (len == 0) {                // timeout (partial packet read)                logERROR(LOGSRC,"Timeoout");                return 0;            }            if (*b == PACKET_ASCII_ENCODING_EOL) {                *b = 0;                break;            }        }        if ((b - buf) < bufLen) {            readLen = (b - buf);        } else {            // overflow (just close socket) - (unlikely to occur)            logERROR(LOGSRC,"Read overflow");            return -1;        }    } else    if (buf[PACKET_HEADER_LENGTH - 1] != 0) {        // read 'b[2]' bytes        UInt16 payloadLen = (UInt16)buf[PACKET_HEADER_LENGTH - 1];        len = _transportRead(b, payloadLen);        if (len < 0) {            logERROR(LOGSRC,"Read error");            return -1;        }        if (len < payloadLen) {            // timeout (partial packet read)            logERROR(LOGSRC,"Timeout");            //ClientPacketType_t hdrType = CLIENT_HEADER_TYPE(buf[0],buf[1]);            //protocolQueueError(0,"%2x%2x", (UInt32)ERROR_PACKET_LENGTH, (UInt32)hdrType);            return -1;        }        readLen = PACKET_HEADER_LENGTH + len;    } else {        readLen = PACKET_HEADER_LENGTH;    }        /* return lengtht */    return readLen;    }// ----------------------------------------------------------------------------/* write packet to transport */static int gprs_transportWritePacket(const UInt8 *buf, int bufLen){        /* transport not open? */    if (!gprsXport.isOpen) {        logERROR(LOGSRC,"Transport is not open");        return -1;    }    /* nothing specified to write */    if (bufLen == 0) {        return 0;    }    /* write data per transport type */    int len = 0;    switch (gprsXport.type) {        case TRANSPORT_SIMPLEX:            // queue data until the close            len = binBufPrintf(&gprsDatagramBuffer, "%*b", bufLen, buf);            return len;        case TRANSPORT_DUPLEX:            len = blueWrite((char*)buf, bufLen);            return len;        default:            logERROR(LOGSRC,"Unknown transport type %d\n", gprsXport.type);            return -1;    }    }// ----------------------------------------------------------------------------static utBool bluePowerOnReset = utTrue;/* initialize transport */

⌨️ 快捷键说明

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