00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
00077
00078
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
00092 virtual bool Open(const PString & device);
00093 virtual bool Close();
00094
00095
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 { return true; }
00206
00207 virtual bool SetPlayVolume(unsigned volume)
00208 { 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