Yate
|
00001 /* 00002 * yatemodem.h 00003 * This file is part of the YATE Project http://YATE.null.ro 00004 * 00005 * Yet Another Modem 00006 * 00007 * Yet Another Telephony Engine - a fully featured software PBX and IVR 00008 * Copyright (C) 2004-2006 Null Team 00009 * 00010 * This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with this program; if not, write to the Free Software 00022 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 00023 */ 00024 00025 #ifndef __YATEMODEM_H 00026 #define __YATEMODEM_H 00027 00028 #include <yateclass.h> 00029 00030 #ifdef _WINDOWS 00031 00032 #ifdef LIBYMODEM_EXPORTS 00033 #define YMODEM_API __declspec(dllexport) 00034 #else 00035 #ifndef LIBYMODEM_STATIC 00036 #define YMODEM_API __declspec(dllimport) 00037 #endif 00038 #endif 00039 00040 #endif /* _WINDOWS */ 00041 00042 #ifndef YMODEM_API 00043 #define YMODEM_API 00044 #endif 00045 00046 00050 namespace TelEngine { 00051 00052 class BitAccumulator; // 1-byte length bit accumulator 00053 class FSKModem; // Frequency Shift Keying modulator/demodulator 00054 class UART; // UART receiver/transmitter 00055 class UARTBuffer; // A byte accumulator used by an UART 00056 class ETSIModem; // An analog signal processor as defined by ETSI 00057 // Internal forward declarations 00058 class BitBuffer; // Used to accumulate all bits to be printed to output 00059 class FSKFilter; // The internal signal filter 00060 00061 00066 class YMODEM_API BitAccumulator 00067 { 00068 public: 00073 inline BitAccumulator(unsigned char dataBits) 00074 : m_crtByte(0), m_crtPos(0), m_dataBits(dataBits), m_oddParity(false) 00075 {} 00076 00081 inline unsigned char dataBits() const 00082 { return m_dataBits; } 00083 00088 inline void dataBits(unsigned char value) { 00089 m_dataBits = value; 00090 reset(); 00091 } 00092 00098 inline unsigned char reset(bool* oddParity = 0) { 00099 unsigned char tmp = m_crtByte; 00100 m_crtByte = m_crtPos = 0; 00101 if (oddParity) 00102 *oddParity = m_oddParity; 00103 m_oddParity = false; 00104 return tmp; 00105 } 00106 00113 inline unsigned int accumulate(bool bit, bool* oddParity = 0) { 00114 if (bit) { 00115 m_crtByte |= (1 << m_crtPos); 00116 m_oddParity = !m_oddParity; 00117 } 00118 m_crtPos++; 00119 if (m_crtPos != m_dataBits) 00120 return 0xffff; 00121 return reset(oddParity); 00122 } 00123 00124 private: 00125 unsigned char m_crtByte; // Current partial byte 00126 unsigned char m_crtPos; // Current free bit position 00127 unsigned char m_dataBits; // The length of a data byte (interval: 1..8) 00128 bool m_oddParity; // The parity of the current byte value (true: odd) 00129 }; 00130 00131 00137 class YMODEM_API FSKModem 00138 { 00139 public: 00143 enum Type { 00144 ETSI = 0, // ETSI caller id signal: MARK:1200 SPACE:2200 BAUDRATE:1200 00145 // SAMPLERATE:8000 SAMPLES/BIT:7 STOPBITS:1 PARITY:NONE 00146 TypeCount = 1 00147 // NOTE: Don't change these values: they are used as array indexes 00148 }; 00149 00155 FSKModem(const NamedList& params, UART* uart); 00156 00160 ~FSKModem(); 00161 00167 inline bool terminated() const 00168 { return m_terminated; } 00169 00174 inline int type() const 00175 { return m_type; } 00176 00180 void reset(); 00181 00187 bool demodulate(const DataBlock& data); 00188 00197 void modulate(DataBlock& dest, const DataBlock& data); 00198 00205 static inline void addRaw(DataBlock& dest, void* buf, unsigned int len) { 00206 DataBlock tmp(buf,len,false); 00207 dest += tmp; 00208 tmp.clear(false); 00209 } 00210 00214 static TokenDict s_typeName[]; 00215 00216 private: 00217 int m_type; // Modem type 00218 bool m_terminated; // Terminated flag (need reset if true) 00219 FSKFilter* m_filter; // Internal filter used to demodulate received data 00220 UART* m_uart; // The UART using this modem's services 00221 DataBlock m_buffer; // Partial input buffer when used to demodulate or modulate data 00222 BitBuffer* m_bits; // Bit buffer used when debugging 00223 }; 00224 00225 00230 class YMODEM_API UART : public DebugEnabler 00231 { 00232 public: 00236 enum State { 00237 Idle, // Not started 00238 BitStart, // Waiting for start bit (SPACE) 00239 BitData, // Accumulate data bits 00240 BitParity, // Waiting for parity bit(s) 00241 BitStop, // Waiting for stop bit (MARK) 00242 UARTError, // Error 00243 }; 00244 00248 enum Error { 00249 EFraming, // Frame error: invalid stop bit(s) 00250 EParity, // Parity error 00251 EChksum, // Message checksum error 00252 EInvalidData, // Invalid (inconsistent) data 00253 EUnknown, // Unknown error 00254 EStopped, // Aborted by descendants 00255 ENone 00256 }; 00257 00264 UART(State state, const NamedList& params, const char* name = 0); 00265 00269 virtual ~UART() 00270 {} 00271 00276 inline State state() const 00277 { return m_state; } 00278 00283 inline Error error() const 00284 { return m_error; } 00285 00290 inline int modemType() const 00291 { return m_modem.type(); } 00292 00297 inline const BitAccumulator& accumulator() const 00298 { return m_accumulator; } 00299 00304 virtual void reset(State newState = Idle); 00305 00311 inline bool demodulate(const DataBlock& data) 00312 { return m_modem.demodulate(data); } 00313 00320 inline bool modulate(DataBlock& dest, NamedList& params) { 00321 DataBlock data; 00322 if (!createMsg(params,data)) 00323 return false; 00324 m_modem.modulate(dest,data); 00325 return true; 00326 } 00327 00333 inline void modulate(DataBlock& dest, const DataBlock& src) 00334 { m_modem.modulate(dest,src); } 00335 00341 bool recvBit(bool value); 00342 00348 virtual bool recvByte(unsigned char data) 00349 { return false; } 00350 00355 virtual bool fskStarted() 00356 { return true; } 00357 00361 static TokenDict s_errors[]; 00362 00363 protected: 00369 virtual int idleRecvByte(unsigned char data) 00370 { return false; } 00371 00378 virtual bool createMsg(NamedList& params, DataBlock& data) 00379 { return false; } 00380 00386 bool error(Error e); 00387 00388 private: 00389 // Change this UART's state 00390 void changeState(State newState); 00391 00392 FSKModem m_modem; // The modem used by this UART 00393 State m_state; // The state of this UART 00394 Error m_error; // The error type if state is error 00395 int m_parity; // Used parity: 0=none, -1=odd, 1=even 00396 bool m_expectedParity; // The expected value of the parity bit if used 00397 BitAccumulator m_accumulator; // The data bits accumulator 00398 }; 00399 00400 00405 class YMODEM_API UARTBuffer 00406 { 00407 public: 00412 inline UARTBuffer(UART* client) 00413 : m_client(client) 00414 { reset(); } 00415 00420 inline const DataBlock& buffer() const 00421 { return m_buffer; } 00422 00427 inline unsigned int free() const 00428 { return m_free; } 00429 00434 inline void reset(unsigned int len = 0) { 00435 m_buffer.clear(); 00436 m_crtIdx = m_free = 0; 00437 if (len) { 00438 m_buffer.assign(0,len); 00439 m_free = len; 00440 } 00441 } 00442 00448 inline bool accumulate(unsigned char value) { 00449 if (m_free) { 00450 ((unsigned char*)m_buffer.data())[m_crtIdx++] = value; 00451 m_free--; 00452 return true; 00453 } 00454 Debug(m_client,DebugNote,"Buffer overflow"); 00455 return false; 00456 } 00457 00458 private: 00459 UART* m_client; // The client 00460 unsigned int m_crtIdx; // Current index n buffer 00461 unsigned int m_free; // Free buffer length 00462 DataBlock m_buffer; // The buffer 00463 }; 00464 00465 00471 class YMODEM_API ETSIModem : public UART 00472 { 00473 public: 00477 enum State { 00478 StateError, // Error encountered: need reset 00479 WaitFSKStart, // Waiting for data start pattern 00480 WaitMark, // Waiting for mark pattern 00481 WaitMsg, // Wait a message 00482 WaitMsgLen, // Received message: wait length 00483 WaitParam, // Wait a parameter 00484 WaitParamLen, // Received parameter: wait length 00485 WaitData, // Received parameter length: wait data 00486 WaitChksum, // Wait checksum 00487 }; 00488 00492 enum MsgType { 00493 MsgCallSetup = 0x80, // Call setup 00494 MsgMWI = 0x82, // Message waiting indicator 00495 MsgCharge = 0x86, // Advise of charge 00496 MsgSMS = 0x89, // Short message service 00497 }; 00498 00502 enum MsgParam { 00503 DateTime = 0x01, // 8 Date and Time 00504 CallerId = 0x02, // max. 20 Calling Line Identity 00505 CalledId = 0x03, // max. 20 Called Line Identity 00506 CallerIdReason = 0x04, // 1 Reason for Absence of Calling Line Identity 00507 CallerName = 0x07, // max. 50 Calling Party Name 00508 CallerNameReason = 0x08, // 1 Reason for absence of Calling Party Name 00509 VisualIndicator = 0x0B, // 1 Visual Indicator 00510 MessageId = 0x0D, // 3 Message Identification 00511 LastMsgCLI = 0x0E, // max. 20 Last Message CLI 00512 CompDateTime = 0x0F, // 8 or 10 Complementary Date and Time 00513 CompCallerId = 0x10, // max. 20 Complementary Calling Line Identity 00514 CallType = 0x11, // 1 Call type 00515 FirstCalledId = 0x12, // max. 20 First Called Line Identity 00516 MWICount = 0x13, // 1 Number of Messages 00517 FwdCallType = 0x15, // 1 Type of Forwarded call 00518 CallerType = 0x16, // 1 Type of Calling user 00519 RedirNumber = 0x1A, // max. 20 Redirecting Number 00520 Charge = 0x20, // 14 Charge 00521 AdditionalCharge = 0x21, // 14 Additional Charge 00522 Duration = 0x23, // 6 Duration of the Call 00523 NetworkID = 0x30, // max. 20 Network Provider Identity 00524 CarrierId = 0x31, // max. 20 Carrier Identity 00525 SelectFunction = 0x40, // 2-21 Selection of Terminal Function 00526 Display = 0x50, // max. 253 Display Information 00527 ServiceInfo = 0x55, // 1 Service Information 00528 Extension = 0xE0, // 10 Extension for network operator use 00529 Unknown 00530 }; 00531 00537 ETSIModem(const NamedList& params, const char* name = 0); 00538 00542 virtual ~ETSIModem(); 00543 00547 virtual void reset(); 00548 00554 virtual bool recvByte(unsigned char data); 00555 00559 static TokenDict s_msg[]; 00560 00564 static TokenDict s_msgParams[]; 00565 00566 protected: 00572 virtual int idleRecvByte(unsigned char data); 00573 00580 virtual bool recvParams(MsgType msg, const NamedList& params) 00581 { return false; } 00582 00589 virtual bool decode(MsgType msg, const DataBlock& buffer); 00590 00598 virtual bool createMsg(NamedList& params, DataBlock& data); 00599 00600 private: 00601 // Change decoder's state 00602 void changeState(State newState); 00603 00604 UARTBuffer m_buffer; // The buffer used to accumulate messages 00605 State m_state; // Decoder state 00606 unsigned char m_waitSeizureCount; // Expected number of channel seizure bytes in a row 00607 unsigned char m_crtSeizureCount; // Current number of channel seizure bytes in a row 00608 unsigned char m_crtMsg; // Current message id 00609 unsigned char m_crtParamLen; // Current receiving parameter length 00610 unsigned int m_chksum; // Current calculated checksum 00611 }; 00612 00613 } 00614 00615 #endif /* __YATEMODEM_H */ 00616 00617 /* vi: set ts=8 sw=4 sts=4 noet: */