1 /*
2 *
3 * Inter Asterisk Exchange 2
4 *
5 * Implementation of the classes to carry Information Elements
6 *
7 * Open Phone Abstraction Library (OPAL)
8 *
9 * Copyright (c) 2005 Indranet Technologies Ltd.
10 *
11 * The contents of this file are subject to the Mozilla Public License
12 * Version 1.0 (the "License"); you may not use this file except in
13 * compliance with the License. You may obtain a copy of the License at
14 * http://www.mozilla.org/MPL/
15 *
16 * Software distributed under the License is distributed on an "AS IS"
17 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
18 * the License for the specific language governing rights and limitations
19 * under the License.
20 *
21 * The Original Code is Open Phone Abstraction Library.
22 *
23 * The Initial Developer of the Original Code is Indranet Technologies Ltd.
24 *
25 * The author of this code is Derek J Smithies
26 *
27 * $Revision: 25595 $
28 * $Author: rjongbloed $
29 * $Date: 2011-04-18 22:57:14 -0500 (Mon, 18 Apr 2011) $
30 */
31
32 #include <ptlib.h>
33 #include <opal/buildopts.h>
34 #include <ptclib/random.h>
35
36 #if OPAL_IAX2
37
38 #ifdef P_USE_PRAGMA
39 #pragma implementation "ies.h"
40 #endif
41
42 #include <iax2/ies.h>
43 #include <iax2/frame.h>
44 #include <iax2/causecode.h>
45
46 #include <ptclib/cypher.h>
47
48 #define new PNEW
49
IAX2Ie()50 IAX2Ie::IAX2Ie()
51 {
52 validData = PFalse;
53 }
54
BuildInformationElement(BYTE _typeCode,BYTE length,BYTE * srcData)55 IAX2Ie * IAX2Ie::BuildInformationElement(BYTE _typeCode, BYTE length, BYTE *srcData)
56 {
57 switch (_typeCode) {
58 case ie_calledNumber : return new IAX2IeCalledNumber(length, srcData);
59 case ie_callingNumber : return new IAX2IeCallingNumber(length, srcData);
60 case ie_callingAni : return new IAX2IeCallingAni(length, srcData);
61 case ie_callingName : return new IAX2IeCallingName(length, srcData);
62 case ie_calledContext : return new IAX2IeCalledContext(length, srcData);
63 case ie_userName : return new IAX2IeUserName(length, srcData);
64 case ie_password : return new IAX2IePassword(length, srcData);
65 case ie_capability : return new IAX2IeCapability(length, srcData);
66 case ie_format : return new IAX2IeFormat(length, srcData);
67 case ie_language : return new IAX2IeLanguage(length, srcData);
68 case ie_version : return new IAX2IeVersion(length, srcData);
69 case ie_adsicpe : return new IAX2IeAdsicpe(length, srcData);
70 case ie_dnid : return new IAX2IeDnid(length, srcData);
71 case ie_authMethods : return new IAX2IeAuthMethods(length, srcData);
72 case ie_challenge : return new IAX2IeChallenge(length, srcData);
73 case ie_md5Result : return new IAX2IeMd5Result(length, srcData);
74 case ie_rsaResult : return new IAX2IeRsaResult(length, srcData);
75 case ie_apparentAddr : return new IAX2IeApparentAddr(length, srcData);
76 case ie_refresh : return new IAX2IeRefresh(length, srcData);
77 case ie_dpStatus : return new IAX2IeDpStatus(length, srcData);
78 case ie_callNo : return new IAX2IeCallNo(length, srcData);
79 case ie_cause : return new IAX2IeCause(length, srcData);
80 case ie_iaxUnknown : return new IAX2IeIaxUnknown(length, srcData);
81 case ie_msgCount : return new IAX2IeMsgCount(length, srcData);
82 case ie_autoAnswer : return new IAX2IeAutoAnswer(length, srcData);
83 case ie_musicOnHold : return new IAX2IeMusicOnHold(length, srcData);
84 case ie_transferId : return new IAX2IeTransferId(length, srcData);
85 case ie_rdnis : return new IAX2IeRdnis(length, srcData);
86 case ie_provisioning : return new IAX2IeProvisioning(length, srcData);
87 case ie_aesProvisioning : return new IAX2IeAesProvisioning(length, srcData);
88 case ie_dateTime : return new IAX2IeDateTime(length, srcData);
89 case ie_deviceType : return new IAX2IeDeviceType(length, srcData);
90 case ie_serviceIdent : return new IAX2IeServiceIdent(length, srcData);
91 case ie_firmwareVer : return new IAX2IeFirmwareVer(length, srcData);
92 case ie_fwBlockDesc : return new IAX2IeFwBlockDesc(length, srcData);
93 case ie_fwBlockData : return new IAX2IeFwBlockData(length, srcData);
94 case ie_provVer : return new IAX2IeProvVer(length, srcData);
95 case ie_callingPres : return new IAX2IeCallingPres(length, srcData);
96 case ie_callingTon : return new IAX2IeCallingTon(length, srcData);
97 case ie_callingTns : return new IAX2IeCallingTns(length, srcData);
98 case ie_samplingRate : return new IAX2IeSamplingRate(length, srcData);
99 case ie_causeCode : return new IAX2IeCauseCode(length, srcData);
100 case ie_encryption : return new IAX2IeEncryption(length, srcData);
101 case ie_encKey : return new IAX2IeEncKey(length, srcData);
102 case ie_codecPrefs : return new IAX2IeCodecPrefs(length, srcData);
103 case ie_recJitter : return new IAX2IeReceivedJitter(length, srcData);
104 case ie_recLoss : return new IAX2IeReceivedLoss(length, srcData);
105 case ie_recPackets : return new IAX2IeDroppedFrames(length, srcData);
106 case ie_recDelay : return new IAX2IeReceivedDelay(length, srcData);
107 case ie_recDropped : return new IAX2IeDroppedFrames(length, srcData);
108 case ie_recOoo : return new IAX2IeReceivedOoo(length, srcData);
109 case ie_callToken : return new IAX2IeCallToken(length, srcData);
110 default: PTRACE(1, "Ie\t Invalid IE type code " << ::hex << ((int)_typeCode) << ::dec);
111 };
112
113 return new IAX2IeInvalidElement();
114 }
115
116
PrintOn(ostream & str) const117 void IAX2Ie::PrintOn(ostream & str) const
118 {
119 if (validData)
120 str << setw(17) << Class() << " information element " ;
121 else
122 str << setw(17) << Class() << " information element-invalid data " ;
123 }
124
125
WriteBinary(void * _data,PINDEX & writeIndex)126 void IAX2Ie::WriteBinary(void *_data, PINDEX &writeIndex)
127 {
128 BYTE *data = (BYTE *)_data;
129 data[writeIndex] = GetKeyValue();
130 data[writeIndex + 1] = GetLengthOfData();
131
132 writeIndex +=2;
133
134 WriteBinary(data + writeIndex);
135 writeIndex += GetLengthOfData();
136 }
137
138 ////////////////////////////////////////////////////////////////////////////////
139
IAX2IeNone(BYTE,BYTE *)140 IAX2IeNone::IAX2IeNone(BYTE /*length*/, BYTE * /*srcData*/)
141 {
142 validData = PTrue;
143 }
144
145
PrintOn(ostream & str) const146 void IAX2IeNone::PrintOn(ostream & str) const
147 {
148 str << setw(17) << Class();
149 }
150
151 ////////////////////////////////////////////////////////////////////////////////
152
IAX2IeDateAndTime(BYTE length,BYTE * srcData)153 IAX2IeDateAndTime::IAX2IeDateAndTime(BYTE length, BYTE *srcData)
154 {
155 if (length != sizeof(unsigned int)) {
156 validData = PFalse;
157 return;
158 }
159
160 unsigned int tmp = (srcData[0] << 24) | (srcData[1] << 16) | (srcData[2] << 8) | (srcData[3]);
161 int second = (tmp & 0x1f) << 1;
162 int minute = (tmp >> 5) & 0x3f;
163 int hour = (tmp >> 11) & 0x1f;
164 int day = (tmp >> 16) & 0x1f;
165 int month = (tmp >> 21) & 0x0f;
166 int year = ((tmp >> 25) & 0x7f) + 2000;
167 dataValue = PTime(second, minute, hour, day, month, year, PTime::Local);
168
169 validData = PTrue;
170 }
171
172
PrintOn(ostream & str) const173 void IAX2IeDateAndTime::PrintOn(ostream & str) const
174 {
175 str << setw(17) << Class() << dataValue;
176 }
177
WriteBinary(BYTE * data)178 void IAX2IeDateAndTime::WriteBinary(BYTE *data)
179 {
180 unsigned int second = dataValue.GetSecond() >> 1;
181 unsigned int minute = dataValue.GetMinute() << 5;
182 unsigned int hour = dataValue.GetHour() << 11;
183 unsigned int day = dataValue.GetDay() << 16;
184 unsigned int month = dataValue.GetMonth() << 21;
185 unsigned int year = ((unsigned int)(dataValue.GetYear() - 2000)) << 25;
186
187 unsigned int res = second | minute | hour | day | month | year;
188 data[0] = (BYTE)((res >> 24) & 0xff);
189 data[1] = (BYTE)((res >> 16) & 0xff);
190 data[2] = (BYTE)((res >> 8) & 0xff);
191 data[3] = (BYTE)((res ) & 0xff);
192 }
193 ////////////////////////////////////////////////////////////////////////////////
194
IAX2IeByte(BYTE length,BYTE * srcData)195 IAX2IeByte::IAX2IeByte(BYTE length, BYTE *srcData)
196 : IAX2Ie()
197 {
198 if (length != sizeof(BYTE)) {
199 validData = PFalse;
200 return;
201 }
202
203 validData = PTrue;
204 dataValue = *((BYTE *)srcData);
205 }
206
207
PrintOn(ostream & str) const208 void IAX2IeByte::PrintOn(ostream & str) const
209 {
210 if (validData)
211 str << setw(17) << Class() << " " << ((int) dataValue);
212 else
213 str << setw(17) << Class() << " does not hold valid data" ;
214 }
215
216 ////////////////////////////////////////////////////////////////////////////////
IAX2IeChar(BYTE length,BYTE * srcData)217 IAX2IeChar::IAX2IeChar(BYTE length, BYTE *srcData)
218 : IAX2Ie()
219 {
220 if (length != sizeof(BYTE)) {
221 validData = PFalse;
222 return;
223 }
224
225 validData = PTrue;
226 dataValue = *((char *)srcData);
227 }
228
229
PrintOn(ostream & str) const230 void IAX2IeChar::PrintOn(ostream & str) const
231 {
232 if (validData)
233 str << setw(17) << Class() << " " << dataValue;
234 else
235 str << setw(17) << Class() << " does not hold valid data" ;
236 }
237
238 ////////////////////////////////////////////////////////////////////////////////
239
IAX2IeUShort(BYTE length,BYTE * srcData)240 IAX2IeUShort::IAX2IeUShort(BYTE length, BYTE *srcData)
241 : IAX2Ie()
242 {
243 if (length != sizeof(unsigned short)) {
244 validData = PFalse;
245 return;
246 }
247
248 validData = PTrue;
249 dataValue = (unsigned short)((srcData[0] << 8) | srcData[1]);
250 }
251
252
PrintOn(ostream & str) const253 void IAX2IeUShort::PrintOn(ostream & str) const
254 {
255 if (validData)
256 str << setw(17) << Class() << " " << dataValue << "UShort";
257 else
258 str << setw(17) << Class() << " does not hold valid data" ;
259 }
260
WriteBinary(BYTE * data)261 void IAX2IeUShort::WriteBinary(BYTE *data)
262 {
263 data[0] = (BYTE)((dataValue >> 8) & 0xff);
264 data[1] = (BYTE)(dataValue & 0xff);
265 }
266 ////////////////////////////////////////////////////////////////////////////////
267
IAX2IeShort(BYTE length,BYTE * srcData)268 IAX2IeShort::IAX2IeShort(BYTE length, BYTE *srcData)
269 : IAX2Ie()
270 {
271 if (length != sizeof(short)) {
272 validData = PFalse;
273 return;
274 }
275
276 validData = PTrue;
277 dataValue = (short)((srcData[0] << 8) | srcData[1]);
278 }
279
280
PrintOn(ostream & str) const281 void IAX2IeShort::PrintOn(ostream & str) const
282 {
283 if (validData)
284 str << setw(17) << Class() << " " << dataValue;
285 else
286 str << setw(17) << Class() << " does not hold valid data" ;
287 }
288
WriteBinary(BYTE * data)289 void IAX2IeShort::WriteBinary(BYTE *data)
290 {
291 data[0] = (BYTE)((dataValue >> 8) & 0xff);
292 data[1] = (BYTE)(dataValue & 0xff);
293 }
294 ////////////////////////////////////////////////////////////////////////////////
295
IAX2IeInt(BYTE length,BYTE * srcData)296 IAX2IeInt::IAX2IeInt(BYTE length, BYTE *srcData)
297 : IAX2Ie()
298 {
299 if (length != sizeof(int)) {
300 validData = PFalse;
301 return;
302 }
303
304 validData = PTrue;
305 dataValue = (srcData[0] << 24) | (srcData[1] << 16) | (srcData[2] << 8) | srcData[3];
306 }
307
308
PrintOn(ostream & str) const309 void IAX2IeInt::PrintOn(ostream & str) const
310 {
311 if (validData)
312 str << setw(17) << Class() << " " << dataValue;
313 else
314 str << setw(17) << Class() << " does not hold valid data" ;
315 }
316
WriteBinary(BYTE * data)317 void IAX2IeInt::WriteBinary(BYTE *data)
318 {
319 data[0] = (BYTE)((dataValue >> 24) & 0xff);
320 data[1] = (BYTE)((dataValue >> 16) & 0xff);
321 data[2] = (BYTE)((dataValue >> 8) & 0xff);
322 data[3] = (BYTE)(dataValue & 0xff);
323 }
324
325 ////////////////////////////////////////////////////////////////////////////////
326
IAX2IeUInt(BYTE length,BYTE * srcData)327 IAX2IeUInt::IAX2IeUInt(BYTE length, BYTE *srcData)
328 : IAX2Ie()
329 {
330 if (length != sizeof(unsigned int)) {
331 validData = PFalse;
332 return;
333 }
334
335 validData = PTrue;
336 dataValue = (srcData[0] << 24) | (srcData[1] << 16) | (srcData[2] << 8) | srcData[3];
337 }
338
339
PrintOn(ostream & str) const340 void IAX2IeUInt::PrintOn(ostream & str) const
341 {
342 if (validData)
343 str << setw(17) << Class() << " " << dataValue;
344 else
345 str << setw(17) << Class() << " does not hold valid data" ;
346 }
347
WriteBinary(BYTE * data)348 void IAX2IeUInt::WriteBinary(BYTE *data)
349 {
350 data[0] = (BYTE)((dataValue >> 24) & 0xff);
351 data[1] = (BYTE)((dataValue >> 16) & 0xff);
352 data[2] = (BYTE)((dataValue >> 8) & 0xff);
353 data[3] = (BYTE)(dataValue & 0xff);
354 }
355 ////////////////////////////////////////////////////////////////////////////////
356
IAX2IeString(BYTE length,BYTE * srcData)357 IAX2IeString::IAX2IeString(BYTE length, BYTE *srcData)
358 : IAX2Ie()
359 {
360 validData = PTrue;
361 dataValue = PString((const char *)srcData, length);
362 }
363
364
PrintOn(ostream & str) const365 void IAX2IeString::PrintOn(ostream & str) const
366 {
367 if (validData)
368 str << setw(17) << Class() << " " << dataValue;
369 else
370 str << setw(17) << Class() << " does not hold valid data" ;
371 }
372
WriteBinary(BYTE * data)373 void IAX2IeString::WriteBinary(BYTE *data)
374 {
375 if(validData)
376 memcpy(data, dataValue.GetPointer(), GetLengthOfData());
377 }
378
GetLengthOfData()379 BYTE IAX2IeString::GetLengthOfData()
380 {
381 if (dataValue.GetSize() == 0)
382 return 0;
383 else
384 return (BYTE)(dataValue.GetSize() - 1);
385 }
386
SetData(const PString & newData)387 void IAX2IeString::SetData(const PString & newData)
388 {
389 dataValue = newData;
390 validData = PTrue;
391 }
392
SetData(const char * newData)393 void IAX2IeString::SetData(const char * newData)
394 {
395 dataValue = PString(newData);
396 validData = PTrue;
397 }
398
399 /////////////////////////////////////////////////////////////////////////////
IAX2IeBinary(BYTE length,BYTE * srcData)400 IAX2IeBinary::IAX2IeBinary(BYTE length, BYTE *srcData)
401 : IAX2Ie()
402 {
403 validData = PTrue;
404 if (length == 0)
405 dataValue = PBYTEArray(); /*A zero sized array */
406 else
407 dataValue = PBYTEArray(srcData, length);
408 }
409
PrintOn(ostream & str) const410 void IAX2IeBinary::PrintOn(ostream & str) const
411 {
412 if (validData)
413 str << setw(17) << Class() << " " << dataValue;
414 else
415 str << setw(17) << Class() << " does not hold valid data" ;
416 }
417
WriteBinary(BYTE * data)418 void IAX2IeBinary::WriteBinary(BYTE *data)
419 {
420 if(validData) {
421 memcpy(data, dataValue.GetPointer(), GetLengthOfData());
422 }
423 else {
424 PTRACE(3, "Iax2IeBinary\tError - major error in IAX2IeBinary");
425 PAssertAlways("Attempt to use faulty data");
426 }
427 }
428
GetData(PBYTEArray & answer)429 void IAX2IeBinary::GetData(PBYTEArray & answer)
430 {
431 if (!validData) {
432 answer.SetSize(0);
433 return;
434 }
435
436 answer = dataValue;
437 }
438
CopyData(IAX2IeBinary * src)439 void IAX2IeBinary::CopyData(IAX2IeBinary *src)
440 {
441 dataValue = src->dataValue;
442 validData = src->validData;
443 }
444
SetData(const PBYTEArray & newData)445 void IAX2IeBinary::SetData(const PBYTEArray & newData)
446 {
447 dataValue = newData;
448 validData = PTrue;
449 }
450
451 ////////////////////////////////////////////////////////////////////////////////
452
IAX2IeSockaddrIn(BYTE length,BYTE * srcData)453 IAX2IeSockaddrIn::IAX2IeSockaddrIn(BYTE length, BYTE *srcData)
454 : IAX2Ie()
455 {
456 if (length != sizeof(sockaddr_in)) {
457 validData = PFalse;
458 return;
459 }
460
461 validData = PTrue;
462
463 sockaddr_in a = * (sockaddr_in *)(srcData);
464 portNumber = a.sin_port;
465
466 dataValue = PIPSocket::Address(a.sin_addr);
467 }
468
469
PrintOn(ostream & str) const470 void IAX2IeSockaddrIn::PrintOn(ostream & str) const
471 {
472 if (validData)
473 str << setw(17) << Class() << " " << dataValue << ":" << portNumber;
474 else
475 str << setw(17) << Class() << " does not hold valid data" ;
476 }
477
WriteBinary(BYTE * data)478 void IAX2IeSockaddrIn::WriteBinary(BYTE *data)
479 {
480 sockaddr_in a;
481 memset(&a, 0, sizeof(sockaddr_in));
482 a.sin_addr = (in_addr)dataValue;
483 a.sin_port = (unsigned short)portNumber;
484
485 *((sockaddr_in *)data) = a;
486 }
487
488 ////////////////////////////////////////////////////////////////////////////////
489
IAX2IeBlockOfData(BYTE length,BYTE * srcData)490 IAX2IeBlockOfData::IAX2IeBlockOfData(BYTE length, BYTE *srcData)
491 : IAX2Ie()
492 {
493 validData = PTrue;
494
495 dataValue = PBYTEArray(srcData, length);
496 }
497
498
PrintOn(ostream & str) const499 void IAX2IeBlockOfData::PrintOn(ostream & str) const
500 {
501 str << setw(17) << Class() << " " << dataValue;
502 }
503
504
WriteBinary(BYTE * data)505 void IAX2IeBlockOfData::WriteBinary(BYTE *data)
506 {
507 memcpy(data, dataValue.GetPointer(), dataValue.GetSize());
508 }
509
510
511 ///////////////////////////////////////////////////////////////////////////
PrintOn(ostream & strm) const512 void IAX2IeCallToken::PrintOn(ostream & strm) const
513 {
514 if (validData)
515 strm << Class() << " " << dataValue.GetSize()
516 << " bytes ";
517 else
518 strm << "Invalid contents in " << Class();
519 }
520
521
InitialiseKey()522 void IAX2IeCallToken::InitialiseKey()
523 {
524 PINDEX i;
525 for (i = 0; i < blockSize; i++) {
526 iKeyPad[i] = iKeyValue;
527 oKeyPad[i] = oKeyValue;
528 }
529 PStringStream msg;
530 msg << ::hex << PRandom::Number() << ::dec;
531 secretKey = msg;
532
533 BYTE block[20];
534 memcpy(block, secretKey.GetPointer(), secretKey.GetLength());
535 for (i = 0; i < secretKey.GetLength(); i++) {
536 iKeyPad[i] ^= block[i];
537 oKeyPad[i] ^= block[i];
538 }
539 }
540
WriteKeySequence(PIPSocket::Address & remote)541 void IAX2IeCallToken::WriteKeySequence(PIPSocket::Address & remote)
542 {
543 PString srcTime = PString(PTime().GetTimeInSeconds());
544 PString answer = srcTime + PString("?") + ReportKeySequence(srcTime, remote);
545
546 PBYTEArray data;
547 data.SetSize(answer.GetLength());
548 memcpy(data.GetPointer(), answer.GetPointer(), answer.GetLength());
549 SetData(data);
550 }
551
ValidKeySequence(IAX2IeCallToken & cf,PIPSocket::Address & remote)552 PBoolean IAX2IeCallToken::ValidKeySequence (IAX2IeCallToken & cf,
553 PIPSocket::Address & remote)
554 {
555 time_t startTime = PTime().GetTimeInSeconds();
556 PBYTEArray srcData;
557 cf.GetData(srcData);
558 PString src((const char *)srcData.GetPointer(), srcData.GetSize());
559 PStringList bits = src.Tokenise("?");
560 if (bits.GetSize() != 2)
561 return PFalse;
562 time_t srcTime = bits[0].AsInteger();
563
564 if ((srcTime != startTime) &&
565 (srcTime != (startTime + 1)) &&
566 (srcTime != (startTime + 2)))
567 return PFalse;
568
569 PString keySequence = ReportKeySequence(bits[0], remote);
570
571 return keySequence == bits[1];
572 }
573
574 #if P_SSL
ReportKeySequence(const PString & srcTime,PIPSocket::Address & remote)575 PString IAX2IeCallToken::ReportKeySequence(const PString & srcTime, PIPSocket::Address & remote)
576 {
577 BYTE block[1000];
578
579 memcpy(block, iKeyPad, blockSize);
580 PString message = srcTime + remote.AsString();
581 memcpy(block + blockSize, message.GetPointer(), message.GetLength());
582
583 PMessageDigest::Result bin_digest;
584 PMessageDigestSHA1::Encode((const void *)block,
585 blockSize + message.GetLength(), bin_digest);
586 memcpy(block, oKeyPad, blockSize);
587 const BYTE *data = bin_digest.GetPointer();
588 memcpy(block + blockSize, data, bin_digest.GetSize());
589 PMessageDigestSHA1::Encode((const void *)block,
590 blockSize + bin_digest.GetSize(),
591 bin_digest);
592
593 PString answer;
594 PINDEX max;
595 PINDEX i;
596 for (i = 0, max = bin_digest.GetSize(); i < max ; i++)
597 answer.sprintf("%02x", (unsigned)data[i]);
598
599 return answer;
600 }
601 #else
ReportKeySequence(const PString &,PIPSocket::Address &)602 PString IAX2IeCallToken::ReportKeySequence(const PString &, PIPSocket::Address &)
603 {
604 PAssertAlways("SSL should be enabled in the build when call token is used");
605 return PString::Empty();
606 }
607 #endif
608
609
610 /************
611 These variables are static, as they are only accessed from the
612 IAX2IeCallToken class, and they never ever change during program
613 execution. they are initialised and setup at program startup, which
614 saves time on processing each incoming call packet*/
615
616 /**The key used in generating the SHA1-HMAC hash. Key is required for
617 handling incoming calls. This key is set to a random value (hex
618 representation of a random number, which is in the range of
619 1..2^32 */
620 PString IAX2IeCallToken::secretKey;
621
622 /**Used for generating the SHA1-HMAC hash. Initialised at program
623 startup, saves on time later. */
624 BYTE IAX2IeCallToken::iKeyPad[IAX2IeCallToken::blockSize];
625
626 /**Similar to the iKeyPad, an internal variable*/
627 BYTE IAX2IeCallToken::oKeyPad[IAX2IeCallToken::blockSize];
628 /////////////////////////////////////////////////////////////////////////////
629
~IAX2IeList()630 IAX2IeList::~IAX2IeList()
631 {
632 AllowDeleteObjects();
633 }
634
RemoveIeAt(PINDEX i)635 IAX2Ie *IAX2IeList::RemoveIeAt(PINDEX i)
636 {
637 if (i >= GetSize())
638 return NULL;
639
640 return (IAX2Ie *) PAbstractList::RemoveAt(i);
641 }
642
RemoveLastIe()643 IAX2Ie *IAX2IeList::RemoveLastIe()
644 {
645 PINDEX elems = PAbstractList::GetSize();
646 if (elems > 0) {
647 return RemoveIeAt(elems - 1);
648 }
649
650 return NULL;
651 }
652
DeleteAt(PINDEX idex)653 void IAX2IeList::DeleteAt(PINDEX idex)
654 {
655 if (idex >= PAbstractList::GetSize())
656 return;
657
658 IAX2Ie *obj = RemoveIeAt(idex);
659
660 delete obj;
661 }
662
GetBinaryDataSize() const663 int IAX2IeList::GetBinaryDataSize() const
664 {
665 PINDEX totalSize = 0;
666 for (PINDEX i = 0; i < PAbstractList::GetSize(); i++)
667 totalSize += GetIeAt(i)->GetBinarySize();
668
669 return totalSize;
670 }
671
GetIeAt(int i) const672 IAX2Ie *IAX2IeList::GetIeAt(int i) const
673 {
674 if (i >= GetSize())
675 return NULL;
676
677 return (IAX2Ie *)GetAt(i);
678 }
679
680
681 ////////////////////////////////////////////////////////////////////////////////
682
PrintOn(ostream & str) const683 void IAX2IeCalledNumber::PrintOn(ostream & str) const
684 {
685 if (validData)
686 str << setw(17) << Class() << " " << dataValue;
687 else
688 str << setw(17) << Class() << " does not contain valid data";
689 }
690 ////////////////////////////////////////////////////////////////////////////////
691
PrintOn(ostream & str) const692 void IAX2IeCallingNumber::PrintOn(ostream & str) const
693 {
694 if (validData)
695 str << setw(17) << Class() << " " << dataValue;
696 else
697 str << setw(17) << Class() << " does not contain valid data";
698 }
699 ////////////////////////////////////////////////////////////////////////////////
700
PrintOn(ostream & str) const701 void IAX2IeCallingAni::PrintOn(ostream & str) const
702 {
703 if (validData)
704 str << setw(17) << Class() << " " << dataValue;
705 else
706 str << setw(17) << Class() << " does not contain valid data";
707 }
708 ////////////////////////////////////////////////////////////////////////////////
709
PrintOn(ostream & str) const710 void IAX2IeCallingName::PrintOn(ostream & str) const
711 {
712 if (validData)
713 str << setw(17) << Class() << " " << dataValue;
714 else
715 str << setw(17) << Class() << " does not contain valid data";
716 }
717 ////////////////////////////////////////////////////////////////////////////////
718
PrintOn(ostream & str) const719 void IAX2IeCalledContext::PrintOn(ostream & str) const
720 {
721 if (validData)
722 str << setw(17) << Class() << " " << dataValue;
723 else
724 str << setw(17) << Class() << " does not contain valid data";
725 }
726 ////////////////////////////////////////////////////////////////////////////////
727
PrintOn(ostream & str) const728 void IAX2IeUserName::PrintOn(ostream & str) const
729 {
730 if (validData)
731 str << setw(17) << Class() << " " << dataValue;
732 else
733 str << setw(17) << Class() << " does not contain valid data";
734 }
735 ////////////////////////////////////////////////////////////////////////////////
736
PrintOn(ostream & str) const737 void IAX2IePassword::PrintOn(ostream & str) const
738 {
739 if (validData)
740 str << setw(17) << Class() << " " << dataValue;
741 else
742 str << setw(17) << Class() << " does not contain valid data";
743 }
744 ////////////////////////////////////////////////////////////////////////////////
745
PrintOn(ostream & str) const746 void IAX2IeCapability::PrintOn(ostream & str) const
747 {
748 if (validData)
749 str << setw(17) << Class() << " " << dataValue;
750 else
751 str << setw(17) << Class() << " does not contain valid data";
752 }
753 ////////////////////////////////////////////////////////////////////////////////
754
PrintOn(ostream & str) const755 void IAX2IeFormat::PrintOn(ostream & str) const
756 {
757 if (validData)
758 str << setw(17) << Class() << " " << dataValue;
759 else
760 str << setw(17) << Class() << " does not contain valid data";
761 }
762 ////////////////////////////////////////////////////////////////////////////////
763
PrintOn(ostream & str) const764 void IAX2IeLanguage::PrintOn(ostream & str) const
765 {
766 if (validData)
767 str << setw(17) << Class() << " " << dataValue;
768 else
769 str << setw(17) << Class() << " does not contain valid data";
770 }
771 ////////////////////////////////////////////////////////////////////////////////
772
PrintOn(ostream & str) const773 void IAX2IeVersion::PrintOn(ostream & str) const
774 {
775 if (validData)
776 str << setw(17) << Class() << " " << dataValue;
777 else
778 str << setw(17) << Class() << " does not contain valid data";
779 }
780 ////////////////////////////////////////////////////////////////////////////////
781
PrintOn(ostream & str) const782 void IAX2IeAdsicpe::PrintOn(ostream & str) const
783 {
784 if (validData)
785 str << setw(17) << Class() << " " << dataValue;
786 else
787 str << setw(17) << Class() << " does not contain valid data";
788 }
789 ////////////////////////////////////////////////////////////////////////////////
790
PrintOn(ostream & str) const791 void IAX2IeDnid::PrintOn(ostream & str) const
792 {
793 if (validData)
794 str << setw(17) << Class() << " " << dataValue;
795 else
796 str << setw(17) << Class() << " does not contain valid data";
797 }
798 ////////////////////////////////////////////////////////////////////////////////
799
PrintOn(ostream & str) const800 void IAX2IeAuthMethods::PrintOn(ostream & str) const
801 {
802 if (validData)
803 str << setw(17) << Class() << " " << dataValue;
804 else
805 str << setw(17) << Class() << " does not contain valid data";
806 }
807 ////////////////////////////////////////////////////////////////////////////////
808
PrintOn(ostream & str) const809 void IAX2IeChallenge::PrintOn(ostream & str) const
810 {
811 if (validData)
812 str << setw(17) << Class() << " " << dataValue;
813 else
814 str << setw(17) << Class() << " does not contain valid data";
815 }
816 ////////////////////////////////////////////////////////////////////////////////
817
IAX2IeMd5Result(IAX2Encryption & encryption)818 IAX2IeMd5Result::IAX2IeMd5Result(IAX2Encryption & encryption)
819 {
820 InitializeChallengePassword(encryption.ChallengeKey(), encryption.EncryptionKey());
821 }
822
IAX2IeMd5Result(const PString & challenge,const PString & password)823 IAX2IeMd5Result::IAX2IeMd5Result(const PString & challenge, const PString &password)
824 {
825 InitializeChallengePassword(challenge, password);
826 }
827
828
InitializeChallengePassword(const PString & newChallenge,const PString & newPassword)829 void IAX2IeMd5Result::InitializeChallengePassword(const PString &newChallenge, const PString & newPassword)
830 {
831 PMessageDigest5 stomach;
832 stomach.Process(newChallenge);
833 stomach.Process(newPassword);
834 PMessageDigest5::Code digester;
835 stomach.Complete(digester);
836
837 dataBlock.SetSize(sizeof(digester));
838 memcpy(dataBlock.GetPointer(), &digester, dataBlock.GetSize());
839
840 PStringStream res;
841 for (PINDEX i = 0; i < (PINDEX)sizeof(digester); i++)
842 res << ::hex << ::setfill('0') << ::setw(2) << (int)(*(((BYTE *)&digester)+i));
843
844 res.Trim();
845 res.MakeMinimumSize();
846
847 SetData(res);
848
849 PTRACE(3, "IAX2IeMd5Result\tChallenge is " << newChallenge);
850 PTRACE(3, "IAX2IeMd5Result\tPassword is " << newPassword);
851 PTRACE(3, "IAX2IeMd5Result\tresult is " << res);
852 }
853
PrintOn(ostream & str) const854 void IAX2IeMd5Result::PrintOn(ostream & str) const
855 {
856 if (validData)
857 str << setw(17) << Class() << " " << dataValue;
858 else
859 str << setw(17) << Class() << " does not contain valid data";
860 }
861 ////////////////////////////////////////////////////////////////////////////////
862
PrintOn(ostream & str) const863 void IAX2IeRsaResult::PrintOn(ostream & str) const
864 {
865 if (validData)
866 str << setw(17) << Class() << " " << dataValue;
867 else
868 str << setw(17) << Class() << " does not contain valid data";
869 }
870 ////////////////////////////////////////////////////////////////////////////////
871
PrintOn(ostream & str) const872 void IAX2IeApparentAddr::PrintOn(ostream & str) const
873 {
874 if (validData)
875 str << setw(17) << Class() << " " << dataValue;
876 else
877 str << setw(17) << Class() << " does not contain valid data";
878 }
879 ////////////////////////////////////////////////////////////////////////////////
880
PrintOn(ostream & str) const881 void IAX2IeRefresh::PrintOn(ostream & str) const
882 {
883 if (validData)
884 str << setw(17) << Class() << " " << dataValue;
885 else
886 str << setw(17) << Class() << " does not contain valid data";
887 }
888 ////////////////////////////////////////////////////////////////////////////////
889
PrintOn(ostream & str) const890 void IAX2IeDpStatus::PrintOn(ostream & str) const
891 {
892 if (validData)
893 str << setw(17) << Class() << " " << dataValue;
894 else
895 str << setw(17) << Class() << " does not contain valid data";
896 }
897 ////////////////////////////////////////////////////////////////////////////////
898
PrintOn(ostream & str) const899 void IAX2IeCallNo::PrintOn(ostream & str) const
900 {
901 if (validData)
902 str << setw(17) << Class() << " " << dataValue;
903 else
904 str << setw(17) << Class() << " does not contain valid data";
905 }
906 ////////////////////////////////////////////////////////////////////////////////
907
PrintOn(ostream & str) const908 void IAX2IeCause::PrintOn(ostream & str) const
909 {
910 if (validData)
911 str << setw(17) << Class() << " \"" << dataValue;
912 else
913 str << setw(17) << Class() << " does not contain valid data";
914 }
915 ////////////////////////////////////////////////////////////////////////////////
916
PrintOn(ostream & str) const917 void IAX2IeIaxUnknown::PrintOn(ostream & str) const
918 {
919 if (validData)
920 str << setw(17) << Class() << " " << dataValue;
921 else
922 str << setw(17) << Class() << " does not contain valid data";
923 }
924 ////////////////////////////////////////////////////////////////////////////////
925
PrintOn(ostream & str) const926 void IAX2IeMsgCount::PrintOn(ostream & str) const
927 {
928 if (validData)
929 str << setw(17) << Class() << " " << dataValue;
930 else
931 str << setw(17) << Class() << " does not contain valid data";
932 }
933 ////////////////////////////////////////////////////////////////////////////////
934
PrintOn(ostream & str) const935 void IAX2IeAutoAnswer::PrintOn(ostream & str) const
936 {
937 str << setw(17) << Class() << " key(" << ((int) GetKeyValue()) << ")";
938 }
939 ////////////////////////////////////////////////////////////////////////////////
940
PrintOn(ostream & str) const941 void IAX2IeMusicOnHold::PrintOn(ostream & str) const
942 {
943 str << setw(17) << Class() << " key(" << ((int) GetKeyValue()) << ")";
944 }
945 ////////////////////////////////////////////////////////////////////////////////
946
PrintOn(ostream & str) const947 void IAX2IeTransferId::PrintOn(ostream & str) const
948 {
949 if (validData)
950 str << setw(17) << Class() << " " << dataValue;
951 else
952 str << setw(17) << Class() << " does not contain valid data";
953 }
954 ////////////////////////////////////////////////////////////////////////////////
955
PrintOn(ostream & str) const956 void IAX2IeRdnis::PrintOn(ostream & str) const
957 {
958 if (validData)
959 str << setw(17) << Class() << " " << dataValue;
960 else
961 str << setw(17) << Class() << " does not contain valid data";
962 }
963 ////////////////////////////////////////////////////////////////////////////////
964
PrintOn(ostream & str) const965 void IAX2IeProvisioning::PrintOn(ostream & str) const
966 {
967 if (validData)
968 str << setw(17) << Class() << " " << dataValue;
969 else
970 str << setw(17) << Class() << " does not contain valid data";
971 }
972 ////////////////////////////////////////////////////////////////////////////////
973
PrintOn(ostream & str) const974 void IAX2IeAesProvisioning::PrintOn(ostream & str) const
975 {
976 str << setw(17) << Class() << " key(" << ((int) GetKeyValue()) << ")";
977 }
978 ////////////////////////////////////////////////////////////////////////////////
979
PrintOn(ostream & str) const980 void IAX2IeDateTime::PrintOn(ostream & str) const
981 {
982 if (validData)
983 str << setw(17) << Class() << " " << dataValue;
984 else
985 str << setw(17) << Class() << " does not contain valid data";
986 }
987 ////////////////////////////////////////////////////////////////////////////////
988
PrintOn(ostream & str) const989 void IAX2IeDeviceType::PrintOn(ostream & str) const
990 {
991 if (validData)
992 str << setw(17) << Class() << " " << dataValue;
993 else
994 str << setw(17) << Class() << " does not contain valid data";
995 }
996 ////////////////////////////////////////////////////////////////////////////////
997
PrintOn(ostream & str) const998 void IAX2IeServiceIdent::PrintOn(ostream & str) const
999 {
1000 if (validData)
1001 str << setw(17) << Class() << " " << dataValue;
1002 else
1003 str << setw(17) << Class() << " does not contain valid data";
1004 }
1005 ////////////////////////////////////////////////////////////////////////////////
1006
PrintOn(ostream & str) const1007 void IAX2IeFirmwareVer::PrintOn(ostream & str) const
1008 {
1009 if (validData)
1010 str << setw(17) << Class() << " " << dataValue;
1011 else
1012 str << setw(17) << Class() << " does not contain valid data";
1013 }
1014 ////////////////////////////////////////////////////////////////////////////////
1015
PrintOn(ostream & str) const1016 void IAX2IeFwBlockDesc::PrintOn(ostream & str) const
1017 {
1018 if (validData)
1019 str << setw(17) << Class() << " " << dataValue;
1020 else
1021 str << setw(17) << Class() << " does not contain valid data";
1022 }
1023 ////////////////////////////////////////////////////////////////////////////////
1024
PrintOn(ostream & str) const1025 void IAX2IeFwBlockData::PrintOn(ostream & str) const
1026 {
1027 if (validData)
1028 str << setw(17) << Class() << " " << dataValue;
1029 else
1030 str << setw(17) << Class() << " does not contain valid data";
1031 }
1032 ////////////////////////////////////////////////////////////////////////////////
1033
PrintOn(ostream & str) const1034 void IAX2IeProvVer::PrintOn(ostream & str) const
1035 {
1036 if (validData)
1037 str << setw(17) << Class() << " " << dataValue;
1038 else
1039 str << setw(17) << Class() << " does not contain valid data";
1040 }
1041 ////////////////////////////////////////////////////////////////////////////////
1042
PrintOn(ostream & str) const1043 void IAX2IeCallingPres::PrintOn(ostream & str) const
1044 {
1045 if (validData)
1046 str << setw(17) << Class() << " " << dataValue;
1047 else
1048 str << setw(17) << Class() << " does not contain valid data";
1049 }
1050 ////////////////////////////////////////////////////////////////////////////////
1051
PrintOn(ostream & str) const1052 void IAX2IeCallingTon::PrintOn(ostream & str) const
1053 {
1054 if (validData)
1055 str << setw(17) << Class() << " " << dataValue;
1056 else
1057 str << setw(17) << Class() << " does not contain valid data";
1058 }
1059 ////////////////////////////////////////////////////////////////////////////////
1060
PrintOn(ostream & str) const1061 void IAX2IeCallingTns::PrintOn(ostream & str) const
1062 {
1063 if (validData)
1064 str << setw(17) << Class() << " " << dataValue;
1065 else
1066 str << setw(17) << Class() << " does not contain valid data";
1067 }
1068 ////////////////////////////////////////////////////////////////////////////////
1069
PrintOn(ostream & str) const1070 void IAX2IeSamplingRate::PrintOn(ostream & str) const
1071 {
1072 if (validData)
1073 str << setw(17) << Class() << " " << dataValue;
1074 else
1075 str << setw(17) << Class() << " does not contain valid data";
1076 }
1077 ////////////////////////////////////////////////////////////////////////////////
1078
IAX2IeEncryption(IAX2IeEncryptionMethod method)1079 IAX2IeEncryption::IAX2IeEncryption(IAX2IeEncryptionMethod method)
1080 {
1081 SetData((unsigned short)method);
1082 }
1083
PrintOn(ostream & str) const1084 void IAX2IeEncryption::PrintOn(ostream & str) const
1085 {
1086 if (validData)
1087 str << setw(17) << Class() << " " << dataValue;
1088 else
1089 str << setw(17) << Class() << " does not contain valid data";
1090 }
1091 ////////////////////////////////////////////////////////////////////////////////
1092
PrintOn(ostream & str) const1093 void IAX2IeEncKey::PrintOn(ostream & str) const
1094 {
1095 if (validData)
1096 str << setw(17) << Class() << " " << dataValue;
1097 else
1098 str << setw(17) << Class() << " does not contain valid data";
1099 }
1100 ////////////////////////////////////////////////////////////////////////////////
1101
PrintOn(ostream & str) const1102 void IAX2IeCodecPrefs::PrintOn(ostream & str) const
1103 {
1104 if (validData)
1105 str << setw(17) << Class() << " " << dataValue;
1106 else
1107 str << setw(17) << Class() << " does not contain valid data";
1108 }
1109 ////////////////////////////////////////////////////////////////////////////////
PrintOn(ostream & str) const1110 void IAX2IeCauseCode::PrintOn(ostream & str) const
1111 {
1112 if (validData)
1113 str << setw(17) << Class() << " " << ((int)dataValue);
1114 else
1115 str << setw(17) << Class() << " does not contain valid data";
1116 }
1117 ////////////////////////////////////////////////////////////////////////////////
1118
PrintOn(ostream & str) const1119 void IAX2IeReceivedJitter::PrintOn(ostream & str) const
1120 {
1121 if (validData)
1122 str << setw(17) << Class() << " " << ((unsigned int)dataValue);
1123 else
1124 str << setw(17) << Class() << " does not contain valid data";
1125 }
1126
1127 ////////////////////////////////////////////////////////////////////////////////
1128
PrintOn(ostream & str) const1129 void IAX2IeReceivedLoss::PrintOn(ostream & str) const
1130 {
1131 if (validData)
1132 str << setw(17) << Class() << " " << ((unsigned int)dataValue);
1133 else
1134 str << setw(17) << Class() << " does not contain valid data";
1135 }
1136 ////////////////////////////////////////////////////////////////////////////////
PrintOn(ostream & str) const1137 void IAX2IeReceivedFrames::PrintOn(ostream & str) const
1138 {
1139 if (validData)
1140 str << setw(17) << Class() << " " << ((unsigned int)dataValue);
1141 else
1142 str << setw(17) << Class() << " does not contain valid data";
1143 }
1144 ////////////////////////////////////////////////////////////////////////////////
1145
PrintOn(ostream & str) const1146 void IAX2IeReceivedDelay::PrintOn(ostream & str) const
1147 {
1148 if (validData)
1149 str << setw(17) << Class() << " " << ((unsigned short)dataValue);
1150 else
1151 str << setw(17) << Class() << " does not contain valid data";
1152 }
1153
1154 ////////////////////////////////////////////////////////////////////////////////
1155
PrintOn(ostream & str) const1156 void IAX2IeDroppedFrames::PrintOn(ostream & str) const
1157 {
1158 if (validData)
1159 str << setw(17) << Class() << " " << ((unsigned int)dataValue);
1160 else
1161 str << setw(17) << Class() << " does not contain valid data";
1162 }
1163 ////////////////////////////////////////////////////////////////////////////////
1164
PrintOn(ostream & str) const1165 void IAX2IeReceivedOoo::PrintOn(ostream & str) const
1166 {
1167 if (validData)
1168 str << setw(17) << Class() << " " << ((unsigned int)dataValue);
1169 else
1170 str << setw(17) << Class() << " does not contain valid data";
1171 }
1172 ////////////////////////////////////////////////////////////////////////////////
1173
1174
1175 #endif // OPAL_IAX2
1176
1177 ////////////////////////////////////////////////////////////////////////////////
1178 /* The comment below is magic for those who use emacs to edit this file.
1179 * With the comment below, the tab key does auto indent to 2 spaces.
1180 *
1181 * Local Variables:
1182 * mode:c
1183 * c-basic-offset:2
1184 * End:
1185 */
1186
1187