OPAL  Version 3.14.3
dahdi_ep.h
Go to the documentation of this file.
1 /*
2  * dahdi_ep.h
3  *
4  * DAHDI Line Interface Device EndPoint
5  *
6  * Open Phone Abstraction Library
7  *
8  * Copyright (C) 2011 Post Increment
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Opal Library
21  *
22  * The Initial Developer of the Original Code is Post Increment
23  *
24  * Contributor(s): ______________________________________.
25  *
26  * $Revision$
27  * $Author$
28  * $Date$
29  */
30 
31 #ifndef OPAL_LIDS_DAHDI_EP_H
32 #define OPAL_LIDS_DAHDI_EP_H
33 
34 #ifdef P_USE_PRAGMA
35 #pragma interface
36 #endif
37 
38 #include <opal_config.h>
39 
40 #include <ptlib.h>
41 #include <ptlib/mutex.h>
42 #include <ptclib/inetmail.h>
43 #include <ptclib/dtmf.h>
44 
45 #include <lids/lid.h>
46 #include <codec/g711codec.h>
47 
48 #include <dahdi/user.h>
49 
50 #include <unistd.h>
51 #include <sys/ioctl.h>
52 #include <poll.h>
53 #include <signal.h>
54 
55 #include <fcntl.h>
56 #include <errno.h>
57 #include <string.h>
58 #include <stdlib.h>
59 
60 #include <iostream>
61 #include <vector>
62 #include <queue>
63 using namespace std;
64 
66 
68 {
70 
71  public:
72  static const char * DeviceName;
73 
75 
76  // inherited from OpalLineInterfaceDevice
77 
78  // these can be called before Open
79  virtual PString GetDeviceType() const { return "dahdi"; }
80  virtual PString GetDeviceName() const { return DeviceName; }
81  virtual PStringArray GetAllNames() const { PStringArray l; l.AppendString(DeviceName); return l; }
82  virtual PString GetDescription() const { return "DAHDI"; }
83 
84  virtual OpalMediaFormatList GetMediaFormats() const
85  {
87  l += OpalPCM16;
88  return l;
89  }
90 
91  // open the device
92  virtual bool Open(const PString & device);
93  virtual bool Close();
94 
95  // these can be called after Open
96  virtual unsigned GetLineCount() const
97  { return m_channelInfoList.size(); }
98 
99  virtual bool IsLineTerminal(unsigned line)
100  { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->IsFXS(); }
101 
102  virtual bool IsLineOffHook(unsigned line)
103  { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->IsOffHook(); }
104 
105  virtual bool SetLineOffHook(unsigned line, bool newState = true)
106  { if (!IsValidLine(line) || IsLineTerminal(line)) return false; return m_channelInfoList[line]->SetOffHook(newState); }
107 
108  virtual bool PlayTone(unsigned line, CallProgressTones tone) { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->PlayTone(tone); }
109 
110  virtual bool IsTonePlaying(unsigned line) { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->IsTonePlaying(); }
111 
112  virtual bool StopTone(unsigned line) { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->StopTone(); }
113 
114  virtual char ReadDTMF(unsigned line) { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->ReadDTMF(); }
115 
116  virtual PINDEX GetReadFrameSize(unsigned line) { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->GetReadFrameSize(); }
117 
118  virtual PINDEX GetWriteFrameSize(unsigned line) { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->GetWriteFrameSize(); }
119 
120  virtual bool SetReadFrameSize(unsigned line, PINDEX frameSize) { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->SetReadFrameSize(frameSize); }
121  virtual bool SetWriteFrameSize(unsigned line, PINDEX frameSize) { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->SetWriteFrameSize(frameSize); }
122 
123  virtual bool SetReadFormat(unsigned line, const OpalMediaFormat & mediaFormat);
124  virtual bool SetWriteFormat(unsigned line, const OpalMediaFormat & mediaFormat);
125 
126  virtual bool StopReading(unsigned line);
127  virtual bool StopWriting(unsigned line);
128 
129  virtual OpalMediaFormat GetReadFormat(unsigned line)
130  { return OpalG711ALaw; }
131 
132  virtual OpalMediaFormat GetWriteFormat(unsigned line)
133  { return OpalG711ALaw; }
134 
135  virtual bool EnableAudio(unsigned line, bool enable = true)
136  { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->EnableAudio(enable); }
137 
138  virtual bool ReadFrame(unsigned line, void * buf, PINDEX & count)
139  { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->ReadFrame(buf, count); }
140 
141  virtual bool WriteFrame(unsigned line, const void * buf, PINDEX count, PINDEX & written)
142  { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->WriteFrame(buf, count, written); }
143 
144  virtual bool SetRecordVolume(unsigned line, unsigned volume)
145  { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->SetRecordVolume(volume); }
146 
147  virtual bool SetPlayVolume(unsigned line, unsigned volume)
148  { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->SetPlayVolume(volume); }
149 
150  virtual bool GetRecordVolume(unsigned line, unsigned & volume)
151  { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->GetRecordVolume(volume); }
152 
153  virtual bool GetPlayVolume(unsigned line, unsigned & volume)
154  { if (!IsValidLine(line)) return false; return m_channelInfoList[line]->GetPlayVolume(volume); }
155 
156  virtual bool IsAudioEnabled(unsigned line) const { return false; return m_channelInfoList[line]->IsAudioEnabled(); }
157 
158  virtual bool IsValidLine(unsigned line) const { return line < (unsigned)m_channelInfoList.size(); }
159 
160  struct ChannelInfo : public PObject {
161 
162  ChannelInfo(dahdi_params & parms);
163  virtual ~ChannelInfo();
164 
165  virtual bool Open(int samplesPerBlock);
166  virtual bool Close();
167  void ThreadMain();
168 
169  virtual bool IsFXS() { return false; }
170  virtual bool IsOffHook() { return false; }
171  virtual bool IsAudioEnabled() const { return m_audioEnable; }
172  virtual bool IsMediaRunning() const { return m_mediaStarted; }
173 
174  virtual bool IsTonePlaying();
175  virtual bool PlayTone(CallProgressTones tone);
176  virtual bool StopTone();
177 
178  virtual bool EnableAudio(bool enable);
179  virtual bool SetOffHook(bool newState) { return false; }
180 
181  virtual PINDEX GetReadFrameSize() { return m_samplesPerBlock*2; }
182  virtual PINDEX GetWriteFrameSize() { return m_samplesPerBlock*2; }
183  virtual bool SetReadFrameSize(PINDEX frameSize) { return frameSize == m_samplesPerBlock*2; }
184  virtual bool SetWriteFrameSize(PINDEX frameSize) { return frameSize == m_samplesPerBlock*2; }
185 
186  virtual bool ReadFrame(void * buf, PINDEX & count);
187  virtual bool WriteFrame(const void * buf, PINDEX count, PINDEX & written);
188  virtual bool InternalReadFrame(void * buf);
189 
190  virtual bool SetReadFormat(const OpalMediaFormat & mediaFormat);
191  virtual bool SetWriteFormat(const OpalMediaFormat & mediaFormat);
192 
193  virtual bool StopReading();
194  virtual bool StopWriting();
195 
196  virtual bool StartMedia();
197  virtual bool StopMedia();
198 
199  virtual char ReadDTMF();
200 
201  virtual bool LookForEvent();
202  virtual bool DetectTones(void * buffer, int len);
203 
204  virtual bool SetRecordVolume(unsigned volume)
205  { /* m_readVol = volume; */return true; }
206 
207  virtual bool SetPlayVolume(unsigned volume)
208  { /* m_writeVol = volume; */ return true; }
209 
210  virtual bool GetRecordVolume(unsigned & volume)
211  { volume = m_readVol; return true; }
212 
213  virtual bool GetPlayVolume(unsigned & volume)
214  { volume = m_writeVol; return true; }
215 
216  virtual void OnHook() { }
217  virtual void OffHook() { }
218 
219  virtual void Flush();
220 
221  short DecodeSample(BYTE sample);
222  BYTE EncodeSample(short sample);
223 
227 
229  PDTMFDecoder m_dtmfDecoder;
230 
231  PMutex m_mutex;
232  int m_fd;
236 
237  BYTE * m_toneBuffer;
240  bool m_isALaw;
241 
242  PMutex m_dtmfMutex;
243  std::queue<char> m_dtmfQueue;
244 
247 
248  std::vector<BYTE> m_readBuffer;
249  std::vector<BYTE> m_writeBuffer;
250  };
251 
252  struct FXSChannelInfo : public ChannelInfo {
253  FXSChannelInfo(dahdi_params & parms);
254  virtual ~FXSChannelInfo();
255 
256  virtual bool IsOffHook() { return m_hookState == eOffHook; }
257 
258  virtual void OnHook();
259  virtual void OffHook();
260  virtual bool IsFXS() { return true; }
261 
262  enum HookState {
264  eOffHook
265  } m_hookState;
266  };
267 
268  static bool IsDigitalSpan(dahdi_spaninfo & span)
269  { return span.linecompat > 0; }
270 
271  void BuildPollFDs();
272  void ThreadMain();
273 
274  protected:
276  PMutex m_mutex;
277  typedef std::vector<ChannelInfo *> ChannelInfoList;
279 
280  PThread * m_thread;
281  bool m_running;
282  std::vector<pollfd> m_pollFds;
285 };
286 
287 #endif // OPAL_LIDS_DAHDI_EP_H
288 
289