This file is indexed.

/usr/include/sipxtapi/net/SipMessage.h is in libsipxtapi-dev 3.3.0~test17-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
//
// 
// Copyright (C) 2005-2012 SIPez LLC.  All rights reserved.
//
// Copyright (C) 2005, 2006 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2004-2006 Pingtel Corp.  All rights reserved.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
///////////////////////////////////////////////////////////////////////////////

// Author: Dan Petrie (dpetrie AT SIPez DOT com)

#ifndef _SipMessage_h_
#define _SipMessage_h_

// SYSTEM INCLUDES
//#include <...>

// APPLICATION INCLUDES
#include <utl/UtlHashBag.h>
#include <os/OsSocket.h>
#include <net/HttpMessage.h>
#include <net/SdpBody.h>
#include <sdp/SdpCodec.h>
#include <net/Url.h>
#include <net/SmimeBody.h>
#include <tapi/sipXtapi.h>
#include <tapi/sipXtapiEvents.h>


class UtlHashMap;
class SipUserAgent;
class SipRegInfoBody;        // for RFC 3680


// DEFINES

// SIP extensions
#define SIP_CALL_CONTROL_EXTENSION "sip-cc"
#define SIP_SESSION_TIMER_EXTENSION "timer"
#define SIP_REPLACES_EXTENSION "replaces"
#define SIP_JOIN_EXTENSION "join"

// SIP Methods
#define SIP_INVITE_METHOD "INVITE"
#define SIP_ACK_METHOD "ACK"
#define SIP_BYE_METHOD "BYE"
#define SIP_CANCEL_METHOD "CANCEL"
#define SIP_INFO_METHOD "INFO"
#define SIP_NOTIFY_METHOD "NOTIFY"
#define SIP_OPTIONS_METHOD "OPTIONS"
#define SIP_REFER_METHOD "REFER"
#define SIP_REGISTER_METHOD "REGISTER"
#define SIP_SUBSCRIBE_METHOD "SUBSCRIBE"
#define SIP_PING_METHOD         "PING"


//Simple Methods
#define SIP_MESSAGE_METHOD "MESSAGE"
#define SIP_DO_METHOD "DO"
#define SIP_PUBLISH_METHOD "PUBLISH"

// SIP Fields
#define SIP_ACCEPT_FIELD "ACCEPT"
#define SIP_ACCEPT_ENCODING_FIELD HTTP_ACCEPT_ENCODING_FIELD
#define SIP_ACCEPT_LANGUAGE_FIELD HTTP_ACCEPT_LANGUAGE_FIELD
#define SIP_ALLOW_FIELD "ALLOW"
#define SIP_ALSO_FIELD "ALSO"
#define SIP_CALLID_FIELD "CALL-ID"
#define SIP_CONFIG_ALLOW_FIELD "CONFIG_ALLOW"
#define SIP_CONFIG_REQUIRE_FIELD "CONFIG_REQUIRE"
#define SIP_SHORT_CALLID_FIELD "i"
#define SIP_CONTACT_FIELD "CONTACT"
#define SIP_SHORT_CONTACT_FIELD "m"
#define SIP_CONTENT_LENGTH_FIELD HTTP_CONTENT_LENGTH_FIELD
#define SIP_SHORT_CONTENT_LENGTH_FIELD "l"
#define SIP_CONTENT_TYPE_FIELD HTTP_CONTENT_TYPE_FIELD
#define SIP_SHORT_CONTENT_TYPE_FIELD "c"
#define SIP_CONTENT_ENCODING_FIELD "CONTENT-ENCODING"
#define SIP_SHORT_CONTENT_ENCODING_FIELD "e"
#define SIP_CSEQ_FIELD "CSEQ"
#define SIP_DIVERSION_FIELD "DIVERSION"   // draft-levy-sip-diversion-08 Diversion header
#define SIP_EVENT_FIELD "EVENT"
#define SIP_SHORT_EVENT_FIELD "o"
#define SIP_EXPIRES_FIELD "EXPIRES"
#define SIP_FROM_FIELD "FROM"
#define SIP_IF_MATCH_FIELD "SIP-IF-MATCH"
#define SIP_SHORT_FROM_FIELD "f"
#define SIP_MAX_FORWARDS_FIELD "MAX-FORWARDS"
#define SIP_P_ASSERTED_IDENTITY_FIELD "P-ASSERTED-IDENTITY"
#define SIP_Q_FIELD "Q"
#define SIP_REASON_FIELD "REASON"          //  RFC 3326 Reason header
#define SIP_RECORD_ROUTE_FIELD "RECORD-ROUTE"
#define SIP_REFER_TO_FIELD "REFER-TO"
#define SIP_SHORT_REFER_TO_FIELD "r"
#define SIP_REFERRED_BY_FIELD "REFERRED-BY"
#define SIP_SHORT_REFERRED_BY_FIELD "b"
#define SIP_REPLACES_FIELD "REPLACES"
#define SIP_REQUEST_DISPOSITION_FIELD "REQUEST-DISPOSITION"
#define SIP_REQUESTED_BY_FIELD "REQUESTED-BY"
#define SIP_REQUIRE_FIELD "REQUIRE"
#define SIP_PROXY_REQUIRE_FIELD "PROXY-REQUIRE"
#define SIP_ROUTE_FIELD "ROUTE"
#define SIP_SERVER_FIELD "SERVER"
#define SIP_SESSION_EXPIRES_FIELD "SESSION-EXPIRES"
#define SIP_IF_MATCH_FIELD "SIP-IF-MATCH"
#define SIP_ETAG_FIELD "SIP-ETAG"
#define SIP_SUBJECT_FIELD "SUBJECT"
#define SIP_SHORT_SUBJECT_FIELD "s"
#define SIP_SUBSCRIPTION_STATE_FIELD "SUBSCRIPTION-STATE"
#define SIP_SUPPORTED_FIELD "SUPPORTED"
#define SIP_SHORT_SUPPORTED_FIELD "k"
#define SIP_TO_FIELD "TO"
#define SIP_SHORT_TO_FIELD "t"
#define SIP_UNSUPPORTED_FIELD "UNSUPPORTED"
#define SIP_USER_AGENT_FIELD HTTP_USER_AGENT_FIELD
#define SIP_VIA_FIELD "VIA"
#define SIP_SHORT_VIA_FIELD "v"
#define SIP_WARNING_FIELD "WARNING"
#define SIP_MIN_EXPIRES_FIELD "MIN-EXPIRES"

///custom fields
#define SIP_LINE_IDENTIFIER "LINEID"
#define SIPX_IMPLIED_SUB "sipx-implied" ///< integer expiration duration for subscription
// Response codes and text
#define SIP_TRYING_CODE 100
#define SIP_TRYING_TEXT "Trying"

#define SIP_RINGING_CODE 180
#define SIP_RINGING_TEXT "Ringing"

#define SIP_QUEUED_CODE 182
#define SIP_QUEUED_TEXT "Queued"

#define SIP_EARLY_MEDIA_CODE 183
#define SIP_EARLY_MEDIA_TEXT "Session Progress"

#define SIP_2XX_CLASS_CODE 200

#define SIP_OK_CODE 200
#define SIP_OK_TEXT "OK"

#define SIP_ACCEPTED_CODE 202
#define SIP_ACCEPTED_TEXT "Accepted"

#define SIP_3XX_CLASS_CODE 300

#define SIP_MULTI_CHOICE_CODE 300
#define SIP_MULTI_CHOICE_TEXT "Multiple Choices"

#define SIP_PERMANENT_MOVE_CODE 301
#define SIP_PERMANENT_MOVE_TEXT "Moved Permanently"

#define SIP_TEMPORARY_MOVE_CODE 302
#define SIP_TEMPORARY_MOVE_TEXT "Moved Temporarily"

#define SIP_USE_PROXY_CODE 305
#define SIP_USE_PROXY_TXT "Use Proxy"

#define SIP_4XX_CLASS_CODE 400

#define SIP_BAD_REQUEST_CODE 400
#define SIP_BAD_REQUEST_TEXT "Bad Request"

#define SIP_FORBIDDEN_CODE 403
#define SIP_FORBIDDEN_TEXT "Forbidden"

#define SIP_NOT_FOUND_CODE 404
#define SIP_NOT_FOUND_TEXT "Not Found"

#define SIP_BAD_METHOD_CODE 405
#define SIP_BAD_METHOD_TEXT "Method Not Allowed"

#define SIP_REQUEST_TIMEOUT_CODE 408
#define SIP_REQUEST_TIMEOUT_TEXT "Request timeout"

#define SIP_CONDITIONAL_REQUEST_FAILED_CODE 412
#define SIP_CONDITIONAL_REQUEST_FAILED_TEXT "Conditional Request Failed"

#define SIP_BAD_MEDIA_CODE 415
#define SIP_BAD_MEDIA_TEXT "Unsupported Media Type or Content Encoding"

#define SIP_UNSUPPORTED_URI_SCHEME_CODE 416
#define SIP_UNSUPPORTED_URI_SCHEME_TEXT "Unsupported URI Scheme"

#define SIP_BAD_EXTENSION_CODE 420
#define SIP_BAD_EXTENSION_TEXT "Extension Not Supported"

#define SIP_TOO_BRIEF_CODE 423
#define SIP_TOO_BRIEF_TEXT "Registration Too Brief"
#define SIP_SUB_TOO_BRIEF_TEXT "Subscription Too Brief"

#define SIP_BAD_TRANSACTION_CODE 481
#define SIP_BAD_TRANSACTION_TEXT "Transaction Does Not Exist"

#define SIP_LOOP_DETECTED_CODE 482
#define SIP_LOOP_DETECTED_TEXT "Loop Detected"

#define SIP_TOO_MANY_HOPS_CODE 483
#define SIP_TOO_MANY_HOPS_TEXT "Too many hops"

#define SIP_BAD_ADDRESS_CODE 484
#define SIP_BAD_ADDRESS_TEXT "Address Incomplete"

#define SIP_BUSY_CODE 486
#define SIP_BUSY_TEXT "Busy Here"

#define SIP_REQUEST_TERMINATED_CODE 487
#define SIP_REQUEST_TERMINATED_TEXT "Request Terminated"

#define SIP_REQUEST_NOT_ACCEPTABLE_HERE_CODE 488
#define SIP_REQUEST_NOT_ACCEPTABLE_HERE_TEXT "Not Acceptable Here"

#define SIP_BAD_EVENT_CODE 489
#define SIP_BAD_EVENT_TEXT "Requested Event Type Is Not Supported"

#define SIP_REQUEST_PENDING_CODE 491
#define SIP_REQUEST_PENDING_TEXT "Request Pending"   

#define SIP_REQUEST_UNDECIPHERABLE_CODE 493
#define SIP_REQUEST_UNDECIPHERABLE_TEXT "Request Contained an Undecipherable S/MIME body"

#define SIP_5XX_CLASS_CODE 500

#define SIP_SERVER_INTERNAL_ERROR_CODE 500
#define SIP_SERVER_INTERNAL_ERROR_TEXT "Internal Server Error"

#define SIP_UNIMPLEMENTED_METHOD_CODE 501
#define SIP_UNIMPLEMENTED_METHOD_TEXT "Not Implemented"

#define SIP_SERVICE_UNAVAILABLE_CODE 503
#define SIP_SERVICE_UNAVAILABLE_TEXT "Service Unavailable"

#define SIP_BAD_VERSION_CODE 505
#define SIP_BAD_VERSION_TEXT "Version Not Supported"

#define SIP_6XX_CLASS_CODE 600

#define SIP_GLOBAL_BUSY_CODE 600
#define SIP_GLOBAL_BUSY_TEXT "Busy Everywhere"

#define SIP_DECLINE_CODE 603
#define SIP_DECLINE_TEXT "Declined"

// Warning codes
#define SIP_WARN_MEDIA_NAVAIL_CODE 304
#define SIP_WARN_MEDIA_NAVAIL_TEXT "Media type not available"
#define SIP_WARN_MEDIA_INCOMPAT_CODE 305
#define SIP_WARN_MEDIA_INCOMPAT_TEXT "Insufficient compatible media types"
#define SIP_WARN_MISC_CODE 399

// Transport stuff
#define SIP_PORT 5060
#define SIP_TLS_PORT 5061
#define SIP_PROTOCOL_VERSION "SIP/2.0"
#define SIP_SUBFIELD_SEPARATOR " "
#define SIP_SUBFIELD_SEPARATORS "\t "
#define SIP_MULTIFIELD_SEPARATOR ","
#define SIP_SINGLE_SPACE " "
#define SIP_MULTIFIELD_SEPARATORS "\t ,"
#define SIP_TRANSPORT_UDP "UDP"
#define SIP_TRANSPORT_TCP "TCP"
#define SIP_TRANSPORT_TLS "TLS"
#define SIP_URL_TYPE "SIP:"
#define SIPS_URL_TYPE "SIPS:"
#define SIP_DEFAULT_MAX_FORWARDS 70

// Caller preference request dispostions tokens
#define SIP_DISPOSITION_QUEUE "QUEUE"

// NOTIFY method event types
#define SIP_EVENT_MESSAGE_SUMMARY           "message-summary"
#define SIP_EVENT_SIMPLE_MESSAGE_SUMMARY    "simple-message-summary"
#define SIP_EVENT_CHECK_SYNC                "check-sync"
#define SIP_EVENT_REFER                     "refer"
#define SIP_EVENT_CONFIG                    "sip-config"
#define SIP_EVENT_UA_PROFILE                "ua-profile"
#define SIP_EVENT_REGISTER                  "reg" //  RFC 3680 
#define SIP_EVENT_PRESENCE                  "presence"

// Event Header Parameters
#define SIP_EVENT_PARAMETER_PROFILE_TYPE    "profile-type"
#define SIP_EVENT_PARAMETER_VENDOR          "vendor"
#define SIP_EVENT_PARAMETER_MODEL           "model"
#define SIP_EVENT_PARAMETER_VERSION         "version"

// NOTIFY Subscription-State values
#define SIP_SUBSCRIPTION_ACTIVE             "active"
#define SIP_SUBSCRIPTION_PENDING            "pending"
#define SIP_SUBSCRIPTION_TERMINATED         "terminated"

// The following are used for the REFER NOTIFY message body contents
#define CONTENT_TYPE_SIP_APPLICATION        "application/sip"
#define CONTENT_TYPE_MESSAGE_SIPFRAG        "message/sipfrag"
#define CONTENT_TYPE_SIMPLE_MESSAGE_SUMMARY "application/simple-message-summary"
#define CONTENT_TYPE_XPRESSA_SCRIPT         "text/xpressa-script"
#define CONTENT_TYPE_VQ_RTCP_XR             "application/vq-rtcpxr"

// Added for RFC 3680 
#define CONTENT_TYPE_REG_INFO 		"application/reg-info+xml"

#define SIP_REFER_SUCCESS_STATUS "SIP/2.0 200 OK\r\n"
#define SIP_REFER_FAILURE_STATUS "SIP/2.0 503 Service Unavailable\r\n"

//Added for Diversion header reason parameters

#define SIP_DIVERSION_UNKNOWN "unknown"
#define SIP_DIVERSION_BUSY "user-busy"
#define SIP_DIVERSION_UNAVAILABLE "unavailable"
#define SIP_DIVERSION_UNCONDITIONAL "unconditional"
#define SIP_DIVERSION_TIMEOFDAY "time-of-day"
#define SIP_DIVERSION_DND "do-not-disturb"
#define SIP_DIVERSION_DEFLECTION "deflection"
#define SIP_DIVERSION_OTOFSERVICE "out-of-service"
#define SIP_DIVERSION_FOLLOWME "follow-me"
#define SIP_DIVERSION_AWAY "away"

// Session-Timer refresher parameter values
#define SIP_REFRESHER_UAC "uac"
#define SIP_REFRESHER_UAS "uas"

// MACROS
// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STRUCTS
// TYPEDEFS
// FORWARD DECLARATIONS
class SipTransaction;

/// Specialization of HttpMessage to contain and manipulate SIP messages
/**
 * @see HttpMessage for the descriptions of the general constructs
 * manipulators and accessors for the three basic parts of a SIP
 * message.  A message can be queried as to whether it is a request or a
 * response via the isResponse method.
 *
 * @nosubgrouping
 */
class SipMessage : public HttpMessage, public ISmimeNotifySink
{
/* //////////////////////////// PUBLIC //////////////////////////////////// */
public:
   // See sipXcall's CpCallManager for more defines

   enum EventSubTypes
   {
       NET_UNSPECIFIED = 0,
       NET_SIP_MESSAGE
   };

/* ============================ CREATORS ================================== */

    //! Construct from a buffer
    SipMessage(const char* messageBytes = NULL,
               int byteCount = -1);

    //! Construct from bytes read from a socket
    SipMessage(OsSocket* inSocket,
              int bufferSize = HTTP_DEFAULT_SOCKET_BUFFER_SIZE);

    //! Copy constructor
    SipMessage(const SipMessage& rSipMessage);

    //! Assignment operator
    SipMessage& operator=(const SipMessage& rhs);

    virtual
    ~SipMessage();
    //:Destructor

/* ============================ MANIPULATORS ============================== */

    static UtlBoolean getShortName( const char* longFieldName,
                                   UtlString* shortFieldName );

    static UtlBoolean getLongName( const char* shortFieldName,
                                  UtlString* longFieldName );

    void replaceShortFieldNames();

    void replaceLongFieldNames();

/* ============================ ACCESSORS ================================= */

    //! @name SIP URL manipulators
    //@{
    static void buildSipUrl(UtlString* url, const char* address,
                            int port = PORT_NONE,
                            const char* protocol = NULL,
                            const char* user = NULL,
                            const char* userLabel = NULL,
                            const char* tag = NULL);

    static void buildReplacesField(UtlString& replacesField,
                                   const char* callId,
                                   const char* fromField,
                                   const char* toFIeld);

    static UtlBoolean parseParameterFromUri(const char* uri,
                                           const char* parameterName,
                                           UtlString* parameterValue);

    static void setUriParameter(UtlString* uri, const char* parameterName,
                                const char* parameterValue);

    static void parseAddressFromUri(const char* uri, UtlString* address,
                                    int* port, UtlString* protocol,
                                    UtlString* user = NULL,
                                    UtlString* userLabel = NULL,
                                    UtlString* tag = NULL);

    static void ParseContactFields(const SipMessage *sipResponse,
                                   const SipMessage* ipRequest,
                                   const UtlString& subFieldName,
                                   int& subFieldValue);

    static void setUriTag(UtlString* uri, const char* tagValue);

    static UtlBoolean getViaTag(const char* viaField,
                           const char* tagName,
                           UtlString& tagValue);
    //@}

    //! @name SIP specific first header line accessors
    //@{
    void setSipRequestFirstHeaderLine(const char* method,
                                      const char* uri,
                                      const char* protocolVersion = SIP_PROTOCOL_VERSION);

    void changeUri(const char* uri);

    void getUri(UtlString* address, int* port,
                UtlString* protocol,
                UtlString* user = NULL) const;
    //@}


    //! @name Request builder methods
    /*! The following set of methods are used for building
     * requests in this message
     */
    //@{
    void setAckData(const char* uri,
                    const char* fromAddress,
                    const char* toAddress,
                    const char* callId,
                    int sequenceNumber = 1);

    void setAckData(const SipMessage* inviteResponse,
                    const SipMessage* inviteRequest,
                    const char* contactUri = NULL,
                    int sessionExpiresSeconds = 0);

    void setAckErrorData(const SipMessage* inviteResponse);

    void setByeData(const char* uri,
                    const char* fromAddress,
                    const char* toAddress,
                    const char* callId,
                    const char* localContact,
                    int sequenceNumber = 1);

    void setByeData(const SipMessage* inviteResponse,
                    const char * lastRespContact,
                    UtlBoolean byeToCallee,
                    int localSequenceNumber,
                    const char* routeField,
                    const char* alsoInviteUri,
                    const char* localContact);

    void setCancelData(const char* fromAddress, const char* toAddress,
                       const char* callId,
                       int sequenceNumber = 1,
                       const char* localContact=NULL);

    void setCancelData(const SipMessage* inviteResponse,
                       const char* localContact=NULL);

    void setInviteData(const char* fromAddress,
                       const char* toAddress,
                       const char * farEndContact,
                       const char* contactUrl,
                       const char* callId,                       
                       int sequenceNumber = 1,
                       int sessionReinviteTimer = 0);

    void setInviteData(const SipMessage* previousInvite,
                       const char* newUri);

    void setReinviteData(SipMessage* invite,
                         const char* farEndContact,
                         const char* contactUrl,
                         UtlBoolean inviteFromThisSide,
                         const char* routeField,
                         int sequenceNumber,
                         int sessionReinviteTimer);

    void setOptionsData(const SipMessage* inviteRequest,
                        const char* LastRespContact,
                        UtlBoolean optionsToCallee,
                        int localCSequenceNumber,
                        const char* routeField,
                        const char* localContact);

    void setNotifyData(SipMessage *subscribeRequest,
                       int lastLocalSequenceNumber,
                       const char* route,
                       const char* stateField = NULL,
                       const char* eventField = NULL,
                       const char* id = NULL);

    void setNotifyData( const char* uri,
                        const char* fromField,
                        const char* toField,
                        const char* callId,
                        int lastNotifyCseq,
                        const char* eventtype,
                        const char* id,
                        const char* state,
                        const char* contact,
                        const char* routeField);

    void setSubscribeData( const char* uri,
                        const char* fromField,
                        const char* toField,
                        const char* callId,
                        int cseq,
                        const char* eventField,
                        const char* acceptField,
                        const char* id,
                        const char* contact,
                        const char* routeField,
                        int expiresInSeconds);

    void setEnrollmentData(const char* uri,
                           const char* fromField,
                           const char* toField,
                           const char* callId,
                           int CSequenceNum,
                           const char* contactUrl,
                           const char* protocolField,
                           const char* profileField,
                           int expiresInSeconds = -1);

    /* RFC 3428 - MWI*/
    void setMessageSummaryData(
                  UtlString& msgSummaryData,
                  const char* msgAccountUri,
                  UtlBoolean bNewMsgs=FALSE,
                  UtlBoolean bVoiceMsgs=FALSE,
                  UtlBoolean bFaxMsgs=FALSE,
                  UtlBoolean bEmailMsgs=FALSE,
                  int numNewMsgs=-1,
                  int numOldMsgs=-1,
                  int numFaxNewMsgs=-1,
                  int numFaxOldMsgs=-1,
                  int numEmailNewMsgs=-1,
                  int numEmailOldMsgs=-1);

    /* RFC 3428 - MWI */
    void setMWIData(const char *method,
				  const char* fromField,
                  const char* toField,
                  const char* uri,
                  const char* contactUrl,
                  const char* callId,
                  int CSeq,
                  UtlString bodyString);

    /* RFC 3680 - Registration event */
    void setRegInfoData(const char *method,
		    const char* fromField,
                  const char* toField,
                  const char* uri,
                  const char* contactUrl,
                  const char* callId,
                  int CSeq,
                  SipRegInfoBody& regInfoBody);

    void setVoicemailData(const char* fromField,
                           const char* toField,
                           const char* Uri,
                           const char* contactUrl,
                           const char* callId,
                           int CSeq,
                           int subscribePeriod = -1);


    void setReferData(const SipMessage* inviteResponse,
                    UtlBoolean byeToCallee,
                    int localSequenceNumber,
                    const char* routeField,
                    const char* contactUrl,
                    const char* remoteContactUrl,
                    const char* transferTargetAddress,
                    const char* targetCallId);

    void setRegisterData(const char* registererUri,
                         const char* registerAsUri,
                         const char* registrarServerUri,
                         const char* takeCallsAtUri,
                         const char* callId,
                         int sequenceNumber,
                         int expiresInSeconds = -1);

    void setRequestData(const char* method,
                        const char* uri,
                        const char* fromAddress,
                        const char* toAddress,
                        const char* callId,
                        int sequenceNumber = 1,
                        const char* contactUrl = NULL);

    //! Set a PUBLISH request
    void setPublishData( const char* uri,
                         const char* fromField,
                         const char* toField,
                         const char* callId,
                         int cseq,
                         const char* eventField,
                         const char* id,
                         const char* sipIfMatchField,
                         int expiresInSeconds,
                         const char* contact);
    /// Apply any header parameters in the request uri to the message
    void applyTargetUriHeaderParams();
    /**
     * There are some special rules implemented by this routine:
     *
     * - The header must not be forbidden by isUrlHeaderAllowed
     *
     * - If the header is a From, then any tag parameter on that
     *   new From header value is removed, and the tag parameter
     *   from the original From header is inserted.  The original
     *   From header value is inserted in an X-Original-From header.
     *
     * - If the header is a Route, it is forced to be a loose route
     *   and inserted as the topmost Route.
     *
     * - If it a unique header per isUrlHeaderUnique, then the new
     *   value replaces the old one.
     *
     * - otherwise, the new header is just added.to the message.
     */

    //@}

    void addSdpBody(int nRtpContacts,
                    UtlString hostAddresses[],
                    int rtpAudioPorts[],
                    int rtcpAudiopPorts[],
                    int rtpVideoPorts[],
                    int rtcpVideoPorts[],
                    RTP_TRANSPORT transportTypes[],
                    int numRtpCodecs,
                    SdpCodec* rtpCodecs[],
                    SdpSrtpParameters* srtpParams,
                    int videoBandwidth,
                    int videoFramerate,
                    const SipMessage* pRequest = NULL,
                    const RTP_TRANSPORT rtpTransportOptions = RTP_TRANSPORT_UDP);

    void setSecurityAttributes(const SIPXTACK_SECURITY_ATTRIBUTES* const pSecurity);
    SIPXTACK_SECURITY_ATTRIBUTES* const getSecurityAttributes() const { return mpSecurity; } 
    bool fireSecurityEvent(const void* pEventData,
                           const enum SIPX_SECURITY_EVENT,
                           const enum SIPX_SECURITY_CAUSE,
                           SIPXTACK_SECURITY_ATTRIBUTES* const pSecurity,
                           void* pCert = NULL,
                           char* szSubjectAltName = NULL) const;
    bool smimeEncryptSdp(const void *pEventData) ;

    //! Accessor to get SDP body, optionally decrypting it if key info. is provided
    const SdpBody* getSdpBody(SIPXTACK_SECURITY_ATTRIBUTES* const pSecurity = NULL,
                              const void* pEventData = NULL) const;


    //! @name Response builders
    /*! The following methods are used to build responses
     * in this message
     */
    //@{
    void setResponseData(const SipMessage* request,
                        int responseCode,
                        const char* responseText,
                        const char* localContact = NULL);

    void setResponseData(int statusCode, const char* statusText,
                        const char* fromAddress,
                        const char* toAddress,
                        const char* callId,
                        int sequenceNumber,
                        const char* sequenceMethod,
                        const char* localContact = NULL);

    void setOkResponseData(const SipMessage* request,
                           const char* localContact = NULL);

    void setRequestTerminatedResponseData(const SipMessage* request);

    virtual void setRequestUnauthorized(const SipMessage* request,
                                const char* authenticationScheme,
                                const char* authenticationRealm,
                                const char* authenticationNonce = NULL,
                                const char* authenticationOpaque = NULL,
                                enum HttpEndpointEnum authEntity = SERVER);

    void setTryingResponseData(const SipMessage* request);

    /// Generate a 488 response (no compatible codecs).
    void setInviteBadCodecs(const SipMessage* inviteRequest,
                            SipUserAgent* ua
                            /**< SipUserAgent from which to extract the
                             *   agent identification for the Warning:
                             *   header.
                             */
       );

    void setInviteForbidden(const SipMessage* request);

    void setRequestBadMethod(const SipMessage* request,
                             const char* allowedMethods);

    void setRequestUnimplemented(const SipMessage* request);

    void setRequestBadExtension(const SipMessage* request,
                                const char* unsuportedExtensions);

    void setRequestBadAddress(const SipMessage* request);

    void setRequestBadVersion(const SipMessage* request);

    void setRequestBadRequest(const SipMessage* request);

    void setRequestBadUrlType(const SipMessage* request);

    void setRequestBadContentEncoding(const SipMessage* request,
                             const char* allowedEncodings);

    void setInviteRingingData(const char* fromAddress, const char* toAddress,
                              const char* callId,
                              int sequenceNumber = 1);

    void setInviteRingingData(const SipMessage* inviteRequest);

    void setQueuedResponseData(const SipMessage* inviteRequest);

    void setRequestPendingData(const SipMessage* inviteRequest);

    void setForwardResponseData(const SipMessage* inviteRequest,
                                const char* forwardAddress);

    void setInviteBusyData(const char* fromAddress, const char* toAddress,
                       const char* callId,
                       int sequenceNumber = 1);

    void setBadTransactionData(const SipMessage* inviteRequest);

    void setLoopDetectedData(const SipMessage* inviteRequest);

    void setInviteBusyData(const SipMessage* inviteRequest);

    void setInviteErrorData(const SipMessage* inviteRequest, int errorCode, const UtlString& errorText);

    void setInviteOkData(const SipMessage* inviteRequest,                         
                         int maxSessionExpiresSeconds,
                         const char* localContact = NULL);

    // Copy INVITE Record-Route headers to 200 OK Route headers, returns Route count
    int setInviteOkRoutes(const SipMessage& inviteRequest);

    void setByeErrorData(const SipMessage* byeRequest);

    void setReferOkData(const SipMessage* referRequest);

    void setReferDeclinedData(const SipMessage* referRequest);

    void setReferFailedData(const SipMessage* referRequest);

    void setEventData(void* pEventData) { mpEventData = pEventData; }
    //@}


    //! @name Specialized header field accessors
    //@{
    UtlBoolean getFieldSubfield(const char* fieldName, int subfieldIndex,
                               UtlString* subfieldValue) const;

    UtlBoolean getContactUri(int addressIndex, UtlString* uri) const;

    UtlBoolean getContactField(int addressIndex,
                              UtlString& contactField) const;

    UtlBoolean getContactEntry(int addressIndex,
                              UtlString* uriAndParameters) const;

    UtlBoolean getContactAddress(int addressIndex,
                                UtlString* contactAddress,
                                int* contactPort,
                                UtlString* protocol,
                                UtlString* user = NULL,
                                UtlString* userLabel = NULL) const;

    void setViaFromRequest(const SipMessage* request);

    /// fills in parameters in topmost via based on actual received information.
    void setReceivedViaParams(const UtlString& fromIpAddress, ///< actual sender ip
                              int              fromPort       ///< actual sender port
                              );

    void addVia(const char* domainName,
                int port,
                const char* protocol,
                const char* branchId = NULL,
                const bool bIncludeRport = false,
                const char* customRouteId = NULL) ;

    void addViaField(const char* viaField, UtlBoolean afterOtherVias = TRUE);

    void setLastViaTag(const char* tagValue,
                       const char* tagName = "received");

    void setCallIdField(const char* callId = NULL);

    void setCSeqField(int sequenceNumber, const char* method);
    void incrementCSeqNumber();

    void setFromField(const char* fromField);

    void setFromField(const char* fromAddress, int fromPort,
                      const char* fromProtocol = NULL,
                      const char* fromUser = NULL,
                      const char* fromLabel = NULL);

    void setRawToField(const char* toField);

    void setRawFromField(const char* toField);

    void setToField(const char* toAddress, int toPort,
                    const char* fromProtocol = NULL,
                    const char* toUser = NULL,
                    const char* toLabel = NULL);
    void setToFieldTag(const char* tagValue);

    void setToFieldTag(int tagValue);

    /// Remove the To field tag and value
    void removeToFieldTag();

    void setExpiresField(int expiresInSeconds);

    void setMinExpiresField(int minimumExpiresInSeconds);

    void setContactField(const char* contactField, int index = 0);

    void setRequestDispositionField(const char* dispositionField);

    void addRequestDisposition(const char* dispositionToken);

    void setWarningField(int code, const char* hostname, const char* text);
    
    void getFromLabel(UtlString* fromLabel) const;

    void getToLabel(UtlString* toLabel) const;

    void getFromField(UtlString* fromField) const;

    void getFromUri(UtlString* uri) const;

    void getFromUrl(Url& url) const;

    void getFromAddress(UtlString* fromAddress, int* fromPort, UtlString* protocol,
                        UtlString* user = NULL, UtlString* userLabel = NULL,
                        UtlString* tag = NULL) const;

    //! Get the identity value from the P-Asserted-Identity header field
    /*! Get the identity from the index'th P-Asserted-Identity header
     *  field if it exists.
     *  \param identity - network asserted SIP identity (name-addr or
     *                  addr-spec format).  Use the Url class to parse the identity
     *  \param index - indicates which occurrance of P-Asserted-Identity header
     *                 to retrieve.
     *  \return TRUE/FALSE if the header of the given index exists
     */
    UtlBoolean getPAssertedIdentityField(UtlString& identity, int index = 0) const;

    //! Remove all of the P-Asserted-Identity header fields
    void removePAssertedIdentityFields();

    //! Add the P-Asserted-Identity value 
    void addPAssertedIdentityField(const UtlString& identity);

    UtlBoolean getResponseSendAddress(UtlString& address,
                                     int& port,
                                     UtlString& protocol) const;

    static void convertProtocolStringToEnum(const char* protocolString,
                        OsSocket::IpProtocolSocketType& protocolEnum);

    static void convertProtocolEnumToString(OsSocket::IpProtocolSocketType protocolEnum,
                                            UtlString& protocolString);

    UtlBoolean getWarningCode(int* warningCode, int index = 0) const;

    // Retrieves the index-th Via: header as it appears in the message,
    // but does not parse Via: headers for ",".
    // You probably want to use getViaFieldSubField().
    UtlBoolean getViaField(UtlString* viaField, int index) const;

    // Retrieves the index-th logical Via: header value, folding together
    // all the Via: headers and parsing ",".
    UtlBoolean getViaFieldSubField(UtlString* viaSubField, int subFieldIndex) const;

    void getLastVia(UtlString* viaAddress,
                    int* viaPort,
                    UtlString* protocol,
                    int* recievedPort = NULL,
                    UtlBoolean* receivedSet = NULL,
                    UtlBoolean* maddrSet = NULL,
                    UtlBoolean* receivedPortSet = NULL) const;

    UtlBoolean removeLastVia();

    void getToField(UtlString* toField) const;

    void getToUri(UtlString* uri) const;

    void getToUrl(Url& url) const;

    void getToAddress(UtlString* toAddress,
                      int* toPort,
                      UtlString* protocol,
                      UtlString* user = NULL,
                      UtlString* userLabel = NULL,
                      UtlString* tag = NULL) const;

    void getCallIdField(UtlString* callId) const;

    void getDialogHandle(UtlString& dialogHandle) const;

    UtlBoolean getCSeqField(int* sequenceNum, UtlString* sequenceMethod) const;

    UtlBoolean getRequireExtension(int extensionIndex, UtlString* extension) const;

    UtlBoolean getProxyRequireExtension(int extensionIndex, UtlString* extension) const;

    void addRequireExtension(const char* extension);

    UtlBoolean getContentEncodingField(UtlString* contentEncodingField) const;

    /// Retrieve the event type, id, and other params from the Event Header
    UtlBoolean getEventField(UtlString* eventType,
                             UtlString* eventId = NULL, //< set to the 'id' parameter value if not NULL
                             UtlHashMap* params = NULL  //< holds parameter name/value pairs if not NULL
                             ) const;

    UtlBoolean getEventField(UtlString& eventField) const;

    void setEventField(const char* eventField);

    UtlBoolean getExpiresField(int* expiresInSeconds) const;

    UtlBoolean getRequestDispositionField(UtlString* dispositionField) const;

    UtlBoolean getRequestDisposition(int tokenIndex,
                                    UtlString* dispositionToken) const;

    UtlBoolean getSessionExpires(int* sessionExpiresSeconds, UtlString* refresher) const;

    void setSessionExpires(int sessionExpiresSeconds, const char* refresher = NULL);

    UtlBoolean getSupportedField(UtlString& supportedField) const;

    void setSupportedField(const char* supportedField);

    //! Test whether "token" is present in the Supported: header.
    UtlBoolean isInSupportedField(const char* token) const;

    //! Get the SIP-IF-MATCH field from the PUBLISH request
    UtlBoolean getSipIfMatchField(UtlString& sipIfMatchField) const;

    //! Set the SIP-IF-MATCH field for a PUBLISH request
    void setSipIfMatchField(const char* sipIfMatchField);

    //! Get the SIP-ETAG field from the response to a PUBLISH request
    UtlBoolean getSipETagField(UtlString& sipETagField) const;

    //! Set the SIP-ETAG field in a response to the PUBLISH request
    void setSipETagField(const char* sipETagField);

    const UtlString& getLocalIp() const;
    
    void setLocalIp(const UtlString& localIp);

    void setTransportInfo(const SipMessage* pMsg) ;

    //@}

    //! @name SIP Routing header field accessors and manipulators
    //@{
    UtlBoolean getMaxForwards(int& maxForwards) const;

    void setMaxForwards(int maxForwards);

    void decrementMaxForwards();

    UtlBoolean getRecordRouteField(int index,
                                  UtlString* recordRouteField) const;

    UtlBoolean getRecordRouteUri(int index, UtlString* recordRouteUri) const;

    void setRecordRouteField(const char* recordRouteField, int index);

    void addRecordRouteUri(const char* recordRouteUri);

    // isClientMsgStrictRouted returns whether or not a message
    //    is set up such that it requires strict routing.
    //    This is appropriate only when acting as a UAC
    UtlBoolean isClientMsgStrictRouted() const;

    UtlBoolean getRouteField(UtlString* routeField) const;

    UtlBoolean getRouteUri(int index, UtlString* routeUri) const;

    void addRouteUri(const char* routeUri);

    void addLastRouteUri(const char* routeUri);

    UtlBoolean getLastRouteUri(UtlString& routeUri,
                              int& lastIndex);

    UtlBoolean removeRouteUri(int index, UtlString* routeUri);

    void setRouteField(const char* routeField);

    UtlBoolean buildRouteField(UtlString* routeField) const;

    /// Adjust route values as required when receiving at a proxy.
    void normalizeProxyRoutes(const SipUserAgent* sipUA, ///< used to check isMyHostAlias
                              Url& requestUri,           ///< returns normalized request uri
                              UtlSList* removedRoutes = NULL // route headers popped 
                              );
    /**<
     * Check the request URI and the topmost route
     *   - Detect and correct for any strict router upstream
     *     as specified by RFC 3261 section 16.4 Route Information Preprocessing
     *   - Pop off the topmost route until it is not me
     *  
     * If the removedRoutes is non-NULL, then any removed routes are returned
     *   on this list (in the order returned - topmost first) as UtlString objects.
     *   The caller is responsible for deleting these UtlStrings (a call to
     *   removedRoutes->destroyAll will delete them all).
     */

    //@}


    //! @name Call control header field accessors
    //@{
    //! Deprecated
    UtlBoolean getAlsoUri(int index, UtlString* alsoUri) const;
    //! Deprecated
    UtlBoolean getAlsoField(UtlString* alsoField) const;
    //! Deprecated
    void setAlsoField(const char* alsoField);
    //! Deprecated
    void addAlsoUri(const char* alsoUri);

    void setRequestedByField(const char* requestedByUri);

    UtlBoolean getRequestedByField(UtlString& requestedByField) const;

    void setReferToField(const char* referToField);

    UtlBoolean getReferToField(UtlString& referToField) const;

    void setReferredByField(const char* referredByField);

    UtlBoolean getReferredByField(UtlString& referredByField) const;

    UtlBoolean getReferredByUrls(UtlString* referrerUrl = NULL,
                                 UtlString* referredToUrl = NULL) const;

    void setAllowField(const char* referToField);

    UtlBoolean getAllowField(UtlString& referToField) const;

    UtlBoolean getReplacesData(UtlString& callId,
                              UtlString& toTag,
                              UtlString& fromTag) const;

    /// @returns true if the message has either a User-Agent or Server header
    bool hasSelfHeader() const;

    // SERVER-header accessors
    void getServerField(UtlString* serverFieldValue) const;
    void setServerField(const char* serverField);
    void setAcceptField(const char* acceptField);
    void setAuthField(const char* authField);

    // RFC 3326 REASON-header
    void setReasonField(const char* reasonField);

    UtlBoolean getReasonField(UtlString& reasonField) const;

	
    // Diversion-header
    void addDiversionField(const char* addr, const char* reasonParam,
    								UtlBoolean afterOtherDiversions=FALSE);

    void addDiversionField(const char* diversionField, UtlBoolean afterOtherDiversions=FALSE);

	
    UtlBoolean getLastDiversionField(UtlString& diversionField,int& lastIndex);

    UtlBoolean getDiversionField(int index, UtlString& diversionField);

    UtlBoolean getDiversionField(int index, UtlString& addr, UtlString& reasonParam);
	
    //@}

    // This method is needed to cover the symetrical situation which is
    // specific to SIP authorization (i.e. authentication and authorize
    // fields may be in either requests or responses
    UtlBoolean verifyMd5Authorization(const char* userId,
                                      const char* password,
                                      const char* nonce,
                                      const char* realm,
                                      const char* uri = NULL,
                                      enum HttpEndpointEnum authEntity = SERVER) const;

    //! @name DNS SRV state accessors
    /*! \note this will be deprecated
     */
    //@{
        //SDUA
    UtlBoolean getDNSField(UtlString * Protocol,
                          UtlString * Address,
                          UtlString * Port) const;
    void setDNSField( const char* Protocol,
                     const char* Address,
                     const char* Port);

    void clearDNSField();
    //@}


    //! Accessor to store transaction reference
    /*! \note the transaction may be NULL
     */
    void setTransaction(SipTransaction* transaction);

    //! Accessor to get transaction reference
    /*! \note the transaction may be NULL
     */
    SipTransaction* getSipTransaction() const;

    //! Accessor to retrieve any transport string from
    /*! \the to-field.  Also determines if it is a custom transport.
     */
    const UtlString getTransportName(bool& bCustom) const;       

    void setUseShortFieldNames(UtlBoolean bUseShortNames)
        { mbUseShortNames = bUseShortNames; } ; 

    UtlBoolean getUseShortFieldNames() const
        { return mbUseShortNames; } ;

/* ============================ INQUIRY =================================== */

    //! Returns TRUE if this a SIP response
    //! as opposed to a request.
    UtlBoolean isResponse() const;

    //! @ Transaction and session related inquiry methods
    //@{
    UtlBoolean isSameMessage(const SipMessage* message,
                            UtlBoolean responseCodesMustMatch = FALSE) const;

    //! Is message part of a server or client transaction?
    /*! \param isOutgoing - the message is to be sent as opposed to received
     */
    UtlBoolean isServerTransaction(UtlBoolean isOutgoing) const;

    UtlBoolean isSameSession(const SipMessage* message) const;
    static UtlBoolean isSameSession(Url& previousUrl, Url& newUrl);
    UtlBoolean isResponseTo(const SipMessage* message) const;
    UtlBoolean isAckFor(const SipMessage* inviteResponse) const;
    
    //SDUA
    UtlBoolean isInviteFor(const SipMessage* inviteRequest) const;
    UtlBoolean isSameTransaction(const SipMessage* message) const;
    //@}

    //
    UtlBoolean isRequestDispositionSet(const char* dispositionToken) const;

    UtlBoolean isRequireExtensionSet(const char* extension) const;

    //! Is this a header parameter we want to allow users or apps. to
    //  pass through in the URL
    static UtlBoolean isUrlHeaderAllowed(const char*);

    //! Does this header allow multiple values, or only one.
    static UtlBoolean isUrlHeaderUnique(const char*);

    static void parseViaParameters( const char* viaField,
                                    UtlContainer& viaParameterList
                                   );
    // ISmimeNotifySink implementations                               
    void OnError(SIPX_SECURITY_EVENT event, SIPX_SECURITY_CAUSE cause);
    bool OnSignature(void* pCert, char* szSubjAltName);        
    bool getFromThisSide() const { return mbFromThisSide; }
    void setFromThisSide(const bool bFromThisSide) { mbFromThisSide = bFromThisSide; }

/* //////////////////////////// PROTECTED ///////////////////////////////// */
protected:

/* //////////////////////////// PRIVATE /////////////////////////////////// */
private:

    SipTransaction* mpSipTransaction;
    mutable SIPXTACK_SECURITY_ATTRIBUTES* mpSecurity;
    mutable void* mpEventData;
    UtlString mCustomRouteId;

    UtlString mLocalIp;
    bool mbFromThisSide;
    UtlBoolean mbUseShortNames;

    //SDUA
    UtlString m_dnsProtocol ;
    UtlString m_dnsAddress ;
    UtlString m_dnsPort ;

    // Class for the singleton object that carries the field properties
    class SipMessageFieldProps
       {
         public:

          SipMessageFieldProps();
          ~SipMessageFieldProps(); 

          UtlHashBag mShortFieldNames;
          UtlHashBag mLongFieldNames;
          // Headers that may not be referenced in a URI header parameter.
          UtlHashBag mDisallowedUrlHeaders;
          // Headers that do not take a list of values.
          UtlHashBag mUniqueUrlHeaders;

          void initNames();
          void initDisallowedUrlHeaders();
          void initUniqueUrlHeaders();
       };

    // Singleton object to carry the field properties.
    static SipMessageFieldProps sSipMessageFieldProps;
};

/* ============================ INLINE METHODS ============================ */

#endif  // _SipMessage_h_