# dahdi_ep.h

Go to the documentation of this file.

    00001 /*
    00002  * dahdi_ep.h
    00003  *
    00004  * DAHDI Line Interface Device EndPoint
    00005  *
    00006  * Open Phone Abstraction Library
    00007  *
    00008  * Copyright (C) 2011 Post Increment
    00009  *
    00010  * The contents of this file are subject to the Mozilla Public License
    00011  * Version 1.0 (the "License"); you may not use this file except in
    00012  * compliance with the License. You may obtain a copy of the License at
    00013  * http://www.mozilla.org/MPL/
    00014  *
    00015  * Software distributed under the License is distributed on an "AS IS"
    00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
    00017  * the License for the specific language governing rights and limitations
    00018  * under the License.
    00019  *
    00020  * The Original Code is Opal Library
    00021  *
    00022  * The Initial Developer of the Original Code is Post Increment
    00023  *
    00024  * Contributor(s): ______________________________________.
    00025  *
    00026  * $Revision$
    00027  * $Author$
    00028  * $Date$
    00029  */
    00030
    00031 #ifndef OPAL_LIDS_DAHDI_EP_H
    00032 #define OPAL_LIDS_DAHDI_EP_H
    00033
    00034 #ifdef P_USE_PRAGMA
    00035 #pragma interface
    00036 #endif
    00037
    00038 #include <opal/buildopts.h>
    00039
    00040 #include <ptlib.h>
    00041 #include <ptlib/mutex.h>
    00042 #include <ptclib/inetmail.h>
    00043 #include <ptclib/dtmf.h>
    00044
    00045 #include <lids/lid.h>
    00046 #include <codec/g711codec.h>
    00047
    00048 #include <dahdi/user.h>
    00049
    00050 #include <unistd.h>
    00051 #include <sys/ioctl.h>
    00052 #include <poll.h>
    00053 #include <signal.h>
    00054
    00055 #include <fcntl.h>
    00056 #include <errno.h>
    00057 #include <string.h>
    00058 #include <stdlib.h>
    00059
    00060 #include <iostream>
    00061 #include <vector>
    00062 #include <queue>
    00063 using namespace std;
    00064
    00066
    00067 class DahdiLineInterfaceDevice : public OpalLineInterfaceDevice
    00068 {
    00069   PCLASSINFO(DahdiLineInterfaceDevice, OpalLineInterfaceDevice);
    00070
    00071   public:
    00072     static const char * DeviceName;
    00073
    00074     DahdiLineInterfaceDevice();
    00075
    00076     // inherited from OpalLineInterfaceDevice
    00077
    00078     // these can be called before Open
    00079     virtual PString GetDeviceType() const    { return "dahdi"; }
    00080     virtual PString GetDeviceName() const    { return DeviceName; }
    00081     virtual PStringArray GetAllNames() const { PStringArray l; l.AppendString(DeviceName); return l; }
    00082     virtual PString GetDescription() const   { return "DAHDI"; }
    00083
    00084     virtual OpalMediaFormatList GetMediaFormats() const
    00085     {
    00086       OpalMediaFormatList l;
    00087       l += OpalPCM16;
    00088       return l;
    00089     }
    00090
    00091     // open the device
    00092     virtual bool Open(const PString & device);
    00093     virtual bool Close();
    00094
    00095     // these can be called after Open
    00096     virtual unsigned GetLineCount() const
    00097     { return m_channelInfoList.size(); }
    00098
    00099     virtual bool IsLineTerminal(unsigned line)
    00100     { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->IsFXS(); }
    00101
    00102     virtual bool IsLineOffHook(unsigned line)
    00103     { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->IsOffHook(); }
    00104
    00105     virtual bool SetLineOffHook(unsigned line, bool newState = true)
    00106     { if (!IsValidLine(line) || IsLineTerminal(line)) return false; return m_channelInfoList[line]->SetOffHook(newState); }
    00107
    00108     virtual bool PlayTone(unsigned line, CallProgressTones tone)   { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->PlayTone(tone); }
    00109
    00110     virtual bool IsTonePlaying(unsigned line)  { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->IsTonePlaying(); }
    00111
    00112     virtual bool StopTone(unsigned line)       { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->StopTone(); }
    00113
    00114     virtual char ReadDTMF(unsigned line)       { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->ReadDTMF(); }
    00115
    00116     virtual PINDEX GetReadFrameSize(unsigned line) { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->GetReadFrameSize(); }
    00117
    00118     virtual PINDEX GetWriteFrameSize(unsigned line) { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->GetWriteFrameSize(); }
    00119
    00120     virtual bool SetReadFrameSize(unsigned line, PINDEX frameSize)   { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->SetReadFrameSize(frameSize); }
    00121     virtual bool SetWriteFrameSize(unsigned line, PINDEX frameSize)  { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->SetWriteFrameSize(frameSize); }
    00122
    00123     virtual bool SetReadFormat(unsigned line, const OpalMediaFormat & mediaFormat);
    00124     virtual bool SetWriteFormat(unsigned line, const OpalMediaFormat & mediaFormat);
    00125
    00126     virtual bool StopReading(unsigned line);
    00127     virtual bool StopWriting(unsigned line);
    00128
    00129     virtual OpalMediaFormat GetReadFormat(unsigned line)
    00130     { return OpalG711ALaw; }
    00131
    00132     virtual OpalMediaFormat GetWriteFormat(unsigned line)
    00133     { return OpalG711ALaw; }
    00134
    00135     virtual bool EnableAudio(unsigned line, bool enable = true)
    00136     { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->EnableAudio(enable); }
    00137
    00138     virtual bool ReadFrame(unsigned line, void * buf, PINDEX & count)
    00139     { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->ReadFrame(buf, count); }
    00140
    00141     virtual bool WriteFrame(unsigned line, const void * buf, PINDEX count, PINDEX & written)
    00142     {  if (!IsValidLine(line)) return false; return m_channelInfoList[line]->WriteFrame(buf, count, written); }
    00143
    00144     virtual bool SetRecordVolume(unsigned line, unsigned volume)
    00145     {  if (!IsValidLine(line)) return false; return m_channelInfoList[line]->SetRecordVolume(volume); }
    00146
    00147     virtual bool SetPlayVolume(unsigned line, unsigned volume)
    00148     {  if (!IsValidLine(line)) return false; return m_channelInfoList[line]->SetPlayVolume(volume); }
    00149
    00150     virtual bool GetRecordVolume(unsigned line, unsigned & volume)
    00151     {  if (!IsValidLine(line)) return false; return m_channelInfoList[line]->GetRecordVolume(volume); }
    00152
    00153     virtual bool GetPlayVolume(unsigned line, unsigned & volume)
    00154     {  if (!IsValidLine(line)) return false; return m_channelInfoList[line]->GetPlayVolume(volume); }
    00155
    00156     virtual bool IsAudioEnabled(unsigned line) const { return false; return m_channelInfoList[line]->IsAudioEnabled(); }
    00157
    00158     virtual bool IsValidLine(unsigned line) const { return line < (unsigned)m_channelInfoList.size(); }
    00159
    00160     struct ChannelInfo : public PObject {
    00161
    00162       ChannelInfo(dahdi_params & parms);
    00163       virtual ~ChannelInfo();
    00164
    00165       virtual bool Open(int samplesPerBlock);
    00166       virtual bool Close();
    00167       void ThreadMain();
    00168
    00169       virtual bool IsFXS()          { return false; }
    00170       virtual bool IsOffHook()      { return false; }
    00171       virtual bool IsAudioEnabled() const { return m_audioEnable; }
    00172       virtual bool IsMediaRunning() const { return m_mediaStarted; }
    00173
    00174       virtual bool IsTonePlaying();
    00175       virtual bool PlayTone(CallProgressTones tone);
    00176       virtual bool StopTone();
    00177
    00178       virtual bool EnableAudio(bool enable);
    00179       virtual bool SetOffHook(bool newState) { return false; }
    00180
    00181       virtual PINDEX GetReadFrameSize()                      { return m_samplesPerBlock*2; }
    00182       virtual PINDEX GetWriteFrameSize()                     { return m_samplesPerBlock*2; }
    00183       virtual bool SetReadFrameSize(PINDEX frameSize)        { return frameSize == m_samplesPerBlock*2; }
    00184       virtual bool SetWriteFrameSize(PINDEX frameSize)       { return frameSize == m_samplesPerBlock*2; }
    00185
    00186       virtual bool ReadFrame(void * buf, PINDEX & count);
    00187       virtual bool WriteFrame(const void * buf, PINDEX count, PINDEX & written);
    00188       virtual bool InternalReadFrame(void * buf);
    00189
    00190       virtual bool SetReadFormat(const OpalMediaFormat & mediaFormat);
    00191       virtual bool SetWriteFormat(const OpalMediaFormat & mediaFormat);
    00192
    00193       virtual bool StopReading();
    00194       virtual bool StopWriting();
    00195
    00196       virtual bool StartMedia();
    00197       virtual bool StopMedia();
    00198
    00199       virtual char ReadDTMF();
    00200
    00201       virtual bool LookForEvent();
    00202       virtual bool DetectTones(void * buffer, int len);
    00203
    00204       virtual bool SetRecordVolume(unsigned volume)
    00205       {  /* m_readVol = volume; */return true; }
    00206
    00207       virtual bool SetPlayVolume(unsigned volume)
    00208       {  /* m_writeVol = volume; */ return true; }
    00209
    00210       virtual bool GetRecordVolume(unsigned & volume)
    00211       {  volume = m_readVol; return true; }
    00212
    00213       virtual bool GetPlayVolume(unsigned & volume)
    00214       {  volume = m_writeVol; return true; }
    00215
    00216       virtual void OnHook() { }
    00217       virtual void OffHook() { }
    00218
    00219       virtual void Flush();
    00220
    00221       short DecodeSample(BYTE sample);
    00222       BYTE EncodeSample(short sample);
    00223
    00224       int m_spanNumber;
    00225       int m_channelNumber;
    00226       int m_chanPos;
    00227
    00228       bool m_hasHardwareToneDetection;
    00229       PDTMFDecoder m_dtmfDecoder;
    00230
    00231       PMutex m_mutex;
    00232       int m_fd;
    00233       int m_samplesPerBlock;
    00234       bool m_audioEnable;
    00235       bool m_mediaStarted;
    00236
    00237       BYTE * m_toneBuffer;
    00238       int m_toneBufferLen;
    00239       int m_toneBufferPos;
    00240       bool m_isALaw;
    00241
    00242       PMutex m_dtmfMutex;
    00243       std::queue<char> m_dtmfQueue;
    00244
    00245       int m_writeVol;
    00246       int m_readVol;
    00247
    00248       std::vector<BYTE> m_readBuffer;
    00249       std::vector<BYTE> m_writeBuffer;
    00250     };
    00251
    00252     struct FXSChannelInfo : public ChannelInfo {
    00253       FXSChannelInfo(dahdi_params & parms);
    00254       virtual ~FXSChannelInfo();
    00255
    00256       virtual bool IsOffHook()   { return m_hookState == eOffHook; }
    00257
    00258       virtual void OnHook();
    00259       virtual void OffHook();
    00260       virtual bool IsFXS()   { return true; }
    00261
    00262       enum HookState {
    00263         eOnHook,
    00264         eOffHook
    00265       } m_hookState;
    00266     };
    00267
    00268     static bool IsDigitalSpan(dahdi_spaninfo & span)
    00269     { return span.linecompat > 0; }
    00270
    00271     void BuildPollFDs();
    00272     void ThreadMain();
    00273
    00274   protected:
    00275     int m_samplesPerBlock;
    00276     PMutex m_mutex;
    00277     typedef std::vector<ChannelInfo *> ChannelInfoList;
    00278     ChannelInfoList m_channelInfoList;
    00279
    00280     PThread * m_thread;
    00281     bool m_running;
    00282     std::vector<pollfd> m_pollFds;
    00283     PMutex m_pollListMutex;
    00284     bool m_pollListDirty;
    00285 };
    00286
    00287 #endif // OPAL_LIDS_DAHDI_EP_H
    00288
    00289