reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
DtmfPayloadContents.cxx
Go to the documentation of this file.
1#if defined(HAVE_CONFIG_H)
2#include "config.h"
3#endif
4
10#include "rutil/Logger.hxx"
13
14#define RESIPROCATE_SUBSYSTEM resip::Subsystem::SDP
15
16using namespace resip;
17using namespace std;
18
19//const DtmfPayloadContents DtmfPayloadContents::Empty;
20
21bool
23{
25 (void)factory;
26 return true;
27}
28
32
34 : Contents(hfv, contentTypes)
35{
36}
37
41
44{
45 if (this != &rhs)
46 {
48 mDtmfPayload = rhs.mDtmfPayload;
49 }
50 return *this;
51}
52
55{
56 return new DtmfPayloadContents(*this);
57}
58
59void
61{
62 mDtmfPayload.parse(pb);
63}
64
67{
68 mDtmfPayload.encode(s);
69 return s;
70}
71
72const Mime&
74{
75 static Mime type("application", "dtmf-relay");
76 return type;
77}
78
80 : mButton(button),
81 mDuration(duration)
82{}
83
88
91{
92 if (this != &rhs)
93 {
94 mButton = rhs.mButton;
95 mDuration = rhs.mDuration;
96 }
97 return *this;
98}
99
100bool
101DtmfPayloadContents::DtmfPayload::isValidButton(const char c)
102{
103 static const char permittedChars[] = "ABCD*#";
104 if(c >= '0' && c <= '9')
105 {
106 return true;
107 }
108 if(strchr(permittedChars, c) != NULL)
109 {
110 return true;
111 }
112 WarningLog(<<"Not a valid DTMF button: " << c);
113 return false;
114}
115
116void
118{
119 const char* anchor = pb.skipWhitespace();
120 Data val;
122 pb.data(val, anchor);
123 if(!isEqualNoCase(val, "Signal"))
124 {
125 ErrLog(<<"first key must be Signal, found: " << val);
126 throw ParseException("first key must be Signal", pb.getContext(), __FILE__, __LINE__);
127 }
128 pb.skipChar();
129 anchor = pb.skipWhitespace();
131 pb.data(val, anchor);
132 if(val.size() != 1)
133 {
134 ErrLog(<<"signal string [" << val << "], size = " << val.size());
135 throw ParseException("Exactly one button character expected in SIP INFO", pb.getContext(), __FILE__, __LINE__);
136 }
137 const char& _button = val[0];
138 if(!isValidButton(_button))
139 {
140 throw ParseException("Invalid DTMF button character found", pb.getContext(), __FILE__, __LINE__);
141 }
142 StackLog(<< "Button=" << _button);
143
144 skipEol(pb);
145 anchor = pb.skipWhitespace();
147 pb.data(val, anchor);
148 if(!isEqualNoCase(val, "Duration"))
149 {
150 ErrLog(<<"second key must be Duration, found: " << val);
151 throw ParseException("second key must be Duration", pb.getContext(), __FILE__, __LINE__);
152 }
153 pb.skipChar();
154 pb.skipWhitespace();
155 int _duration = pb.integer();
156
157 StackLog(<< "Duration = " << _duration);
158 if(_duration < 20 || _duration > 5000)
159 {
160 ErrLog(<<"Invalid duration: " << _duration);
161 throw ParseException("Invalid duration", pb.getContext(), __FILE__, __LINE__);
162 }
163
164 mButton = _button;
165 mDuration = _duration;
166}
167
168unsigned short
170{
171 resip_assert(mButton);
172 unsigned short eventCode = 0;
173 if(mButton >= '0' && mButton <= '9')
174 {
175 eventCode = mButton - '0';
176 }
177 else if(mButton == '*')
178 {
179 eventCode = 10;
180 }
181 else if(mButton == '#')
182 {
183 eventCode = 11;
184 }
185 else if(mButton >= 'A' && mButton <= 'D')
186 {
187 eventCode = 12 + mButton - 'A';
188 }
189 else
190 {
191 resip_assert(0); // unexpected button, should have been caught by the parser
192 }
193
194 return eventCode;
195}
196
199{
200 s << "Signal=" << mButton << Symbols::CRLF;
201 s << "Duration=" << mDuration << Symbols::CRLF;
202 return s;
203}
204
205/* ====================================================================
206 *
207 * Copyright 2014 Daniel Pocock http://danielpocock.com All rights reserved.
208 *
209 * Redistribution and use in source and binary forms, with or without
210 * modification, are permitted provided that the following conditions
211 * are met:
212 *
213 * 1. Redistributions of source code must retain the above copyright
214 * notice, this list of conditions and the following disclaimer.
215 *
216 * 2. Redistributions in binary form must reproduce the above copyright
217 * notice, this list of conditions and the following disclaimer in
218 * the documentation and/or other materials provided with the
219 * distribution.
220 *
221 * 3. Neither the name of the author(s) nor the names of any contributors
222 * may be used to endorse or promote products derived from this software
223 * without specific prior written permission.
224 *
225 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND
226 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
227 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
228 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
229 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
230 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
232 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
233 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
234 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
235 * SUCH DAMAGE.
236 *
237 * ====================================================================
238 *
239 *
240 */
241
#define StackLog(args_)
Definition Logger.hxx:125
#define WarningLog(args_)
Definition Logger.hxx:134
#define ErrLog(args_)
Definition Logger.hxx:137
#define resip_assert(x)
This file needs to work for both C and C++ code.
Base class for all SIP body types.
Definition Contents.hxx:51
Contents & operator=(const Contents &rhs)
Assignment operator.
Definition Contents.cxx:71
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
size_type size() const noexcept
Returns the number of bytes in this Data.
Definition Data.hxx:599
unsigned short getEventCode() const
obtain representation of the button as event code
EncodeStream & encode(EncodeStream &) const
DtmfPayload & operator=(const DtmfPayload &rhs)
virtual Contents * clone() const
duplicate an DtmfPayloadContents object
static const Mime & getStaticType()
virtual EncodeStream & encodeParsed(EncodeStream &str) const
DtmfPayloadContents & operator=(const DtmfPayloadContents &rhs)
virtual void parse(ParseBuffer &pb)
Represents the "media-type" element in the RFC 3261 grammar.
Definition Mime.hxx:20
Provides string-parsing functionality with protection from buffer overflow.
CurrentPosition skipWhitespace()
CurrentPosition skipToChars(const char *cs)
const Data & getContext() const
CurrentPosition skipToOneOf(const char *cs)
CurrentPosition skipChar()
void data(Data &data, const char *start) const
make the passed in data share memory with the buffer (uses Data::Share)
BaseException used to indicate parse failures.
static const char * EQUALS
Definition Symbols.hxx:29
static const char * CRLF
Definition Symbols.hxx:21
dcm! – add UnusedChecking(_enum) below;
bool isEqualNoCase(const Data &left, const Data &right)
Definition Data.hxx:1116
void skipEol(ParseBuffer &pb)
#define EncodeStream