Index: sipfsm.cpp
===================================================================
--- sipfsm.cpp	(revision 8923)
+++ sipfsm.cpp	(working copy)
@@ -935,6 +935,7 @@
             case SIP_REGISTER:    fsm = sipRegistrar;            break;
             case SIP_SUBSCRIBE:   fsm = CreateSubscriberFsm();   break;
             case SIP_MESSAGE:     fsm = CreateIMFsm();           break;
+            case SIP_OPTIONS:     fsm = CreateOptionsFsm();      break;
             default:              fsm = CreateCallFsm();         break;
             }
         }
@@ -980,6 +981,7 @@
     if (Method == "NOTIFY")     return SIP_NOTIFY;
     if (Method == "MESSAGE")    return SIP_MESSAGE;
     if (Method == "INFO")       return SIP_INFO;
+    if (Method == "OPTIONS")    return SIP_OPTIONS;
 
     if (Method == "STATUS")
     {
@@ -1069,6 +1071,13 @@
     return im;
 }
 
+SipOptions *SipFsm::CreateOptionsFsm(QString Url, QString callIdStr)
+{
+    SipOptions *opt = new SipOptions(this, natIp, localPort, sipRegistration, callIdStr);
+    FsmList.append(opt);
+    return opt;
+}
+
 void SipFsm::StopWatchers()
 {
     SipFsmBase *it=FsmList.first();
@@ -3147,6 +3156,51 @@
 
 
 /**********************************************************************
+SipOptions
+
+FSM to handle OPTIONS processing 
+**********************************************************************/
+
+SipOptions::SipOptions(SipFsm *par, QString localIp, int localPort, SipRegistration *reg, QString callIdStr) : SipFsmBase(par)
+{
+    sipLocalIp = localIp;
+    sipLocalPort = localPort;
+    regProxy = reg;
+
+    rxCseq = -1;
+    txCseq = 1;
+    if (callIdStr.length() > 0)
+        CallId.setValue(callIdStr);
+    else
+        CallId.Generate(sipLocalIp);
+    
+    if (regProxy)
+        MyUrl = new SipUrl("", regProxy->registeredAs(), regProxy->registeredTo(), 5060);
+    else
+        MyUrl = new SipUrl("", "MythPhone", sipLocalIp, sipLocalPort);
+    MyContactUrl = new SipUrl("", "", sipLocalIp, sipLocalPort);
+}
+
+SipOptions::~SipOptions()
+{
+    if (MyUrl)
+        delete MyUrl;
+    if (MyContactUrl)
+        delete MyContactUrl;
+    MyUrl = MyContactUrl = 0;
+}
+
+int SipOptions::FSM(int Event, SipMsg *sipMsg, void *Value)
+{
+    // If we get an OPTIONS message, just send a 200 OK
+    ParseSipMsg(Event, sipMsg);
+    BuildSendStatus(200, "OPTIONS", sipMsg->getCSeqValue(), SIP_OPT_CONTACT);
+
+    return SIP_IDLE;
+}
+
+
+/**********************************************************************
 SipNotify
 
 This class notifies the Myth Frontend that there is an incoming call
Index: sipstack.cpp
===================================================================
--- sipstack.cpp	(revision 8923)
+++ sipstack.cpp	(working copy)
@@ -413,7 +413,7 @@
 void SipMsg::decodeRequestLine(QString line)
 {
     QString Token = line.section(' ', 0, 0);
-    if ((Token == "INVITE") || (Token == "ACK") || (Token == "BYE") || (Token == "CANCEL") || (Token == "REGISTER") || (Token == "SUBSCRIBE") || (Token == "NOTIFY") || (Token == "MESSAGE") || (Token == "INFO"))
+    if ((Token == "INVITE") || (Token == "ACK") || (Token == "BYE") || (Token == "CANCEL") || (Token == "REGISTER") || (Token == "SUBSCRIBE") || (Token == "NOTIFY") || (Token == "MESSAGE") || (Token == "INFO") || (Token == "OPTIONS"))
         thisMethod = Token;
     else if (Token == "SIP/2.0")
     {
Index: sipfsm.h
===================================================================
--- sipfsm.h	(revision 8923)
+++ sipfsm.h	(working copy)
@@ -90,7 +90,7 @@
 
 
 // Call States
-#define SIP_IDLE		            0x1
+#define SIP_IDLE                0x1
 #define SIP_OCONNECTING1        0x2    // Invite sent, no response yet
 #define SIP_OCONNECTING2        0x3    // Invite sent, 1xx response
 #define SIP_ICONNECTING         0x4
@@ -159,8 +159,9 @@
 #define SIP_USER_MESSAGE        0x1F00
 #define SIP_KICKWATCH           0x2000
 #define SIP_MODIFYSESSION       0x2100
+#define SIP_OPTIONS             0x2200
 
-#define SIP_CMD(s)              (((s)==SIP_INVITE) || ((s)==SIP_ACK) || ((s)==SIP_BYE) || ((s)==SIP_CANCEL) || ((s)==SIP_REGISTER) || ((s)==SIP_SUBSCRIBE) || ((s)==SIP_NOTIFY) || ((s)==SIP_MESSAGE) || ((s)==SIP_INFO))
+#define SIP_CMD(s)              (((s)==SIP_INVITE) || ((s)==SIP_ACK) || ((s)==SIP_BYE) || ((s)==SIP_CANCEL) || ((s)==SIP_REGISTER) || ((s)==SIP_SUBSCRIBE) || ((s)==SIP_NOTIFY) || ((s)==SIP_MESSAGE) || ((s)==SIP_INFO) || ((s)==SIP_OPTIONS))
 #define SIP_STATUS(s)           (((s)==SIP_INVITESTATUS_2xx) || ((s)==SIP_INVITESTATUS_1xx) || ((s)==SIP_INVITESTATUS_3456xx) || ((s)==SIP_BYTESTATUS) || ((s)==SIP_CANCELSTATUS) || ((s)==SIP_SUBSTATUS) || ((s)==SIP_NOTSTATUS) || ((s)==SIP_MESSAGESTATUS) || ((s)==SIP_INFOSTATUS) )
 #define SIP_MSG(s)              (SIP_CMD(s) || SIP_STATUS(s))
 
@@ -593,6 +594,23 @@
 };
 
 
+class SipOptions : public SipFsmBase
+{
+  public:
+    SipOptions(SipFsm *par, QString localIp, int localPort, SipRegistration *reg, QString callIdStr="");
+    ~SipOptions();
+    virtual int FSM(int Event, SipMsg *sipMsg=0, void *Value=0);
+    virtual QString type() { return "Options"; };
+
+  private:
+    QString sipLocalIp;
+    int sipLocalPort;
+    SipRegistration *regProxy;
+    int rxCseq;
+    int txCseq;
+};
+
+
 class SipFsm : public QWidget
 {
 
@@ -617,6 +635,7 @@
     SipSubscriber *CreateSubscriberFsm();
     SipWatcher *CreateWatcherFsm(QString Url);
     SipIM *CreateIMFsm(QString Url="", QString callIdStr="");
+    SipOptions *CreateOptionsFsm(QString Url="", QString callIdStr="");
     void StopWatchers();
     void SipFsm::KickWatcher(SipUrl *Url);
     void SendIM(QString destUrl, QString CallId, QString imMsg);
