server: MCS Erect Domain and Attach User phase.
authorVic Lee <llyzs@163.com>
Fri, 19 Aug 2011 18:03:48 +0000 (02:03 +0800)
committerVic Lee <llyzs@163.com>
Fri, 19 Aug 2011 18:03:48 +0000 (02:03 +0800)
libfreerdp-core/connection.c
libfreerdp-core/connection.h
libfreerdp-core/mcs.c
libfreerdp-core/mcs.h
libfreerdp-core/peer.c
libfreerdp-core/rdp.c

index 5ee8440..23d16a7 100644 (file)
@@ -190,3 +190,26 @@ boolean rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, STREAM* s)
        return True;
 }
 
+boolean rdp_server_accept_mcs_erect_domain_request(rdpRdp* rdp, STREAM* s)
+{
+       if (!mcs_read_erect_domain_request(rdp->mcs, s))
+               return False;
+
+       rdp->state = CONNECTION_STATE_MCS_ERECT_DOMAIN;
+
+       return True;
+}
+
+boolean rdp_server_accept_mcs_attach_user_request(rdpRdp* rdp, STREAM* s)
+{
+       if (!mcs_read_attach_user_request(rdp->mcs, s))
+               return False;
+
+       if (!mcs_send_attach_user_confirm(rdp->mcs))
+               return False;
+
+       rdp->state = CONNECTION_STATE_MCS_ATTACH_USER;
+
+       return True;
+}
+
index e0f94b5..a38a168 100644 (file)
@@ -35,12 +35,16 @@ enum CONNECTION_STATE
 {
        CONNECTION_STATE_INITIAL = 0,
        CONNECTION_STATE_NEGO,
-       CONNECTION_STATE_MCS_CONNECT
+       CONNECTION_STATE_MCS_CONNECT,
+       CONNECTION_STATE_MCS_ERECT_DOMAIN,
+       CONNECTION_STATE_MCS_ATTACH_USER
 };
 
 boolean rdp_client_connect(rdpRdp* rdp);
 
 boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s);
 boolean rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, STREAM* s);
+boolean rdp_server_accept_mcs_erect_domain_request(rdpRdp* rdp, STREAM* s);
+boolean rdp_server_accept_mcs_attach_user_request(rdpRdp* rdp, STREAM* s);
 
 #endif /* __CONNECTION_H */
index bc61e1f..39ef010 100644 (file)
@@ -247,11 +247,11 @@ boolean mcs_read_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU* domainMCSPDU
  * @param length TPKT length
  */
 
-void mcs_write_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU domainMCSPDU, int length)
+void mcs_write_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU domainMCSPDU, int length, uint8 options)
 {
        tpkt_write_header(s, length);
        tpdu_write_data(s);
-       per_write_choice(s, domainMCSPDU << 2);
+       per_write_choice(s, (domainMCSPDU << 2) | options);
 }
 
 /**
@@ -597,6 +597,25 @@ boolean mcs_send_connect_response(rdpMcs* mcs)
 }
 
 /**
+ * Read MCS Erect Domain Request.\n
+ * @msdn{cc240523}
+ * @param mcs
+ * @param s stream
+ */
+
+boolean mcs_read_erect_domain_request(rdpMcs* mcs, STREAM* s)
+{
+       int length;
+       enum DomainMCSPDU MCSPDU;
+
+       MCSPDU = DomainMCSPDU_ErectDomainRequest;
+       if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length))
+               return False;
+
+       return True;
+}
+
+/**
  * Send MCS Erect Domain Request.\n
  * @msdn{cc240523}
  * @param mcs
@@ -608,7 +627,7 @@ void mcs_send_erect_domain_request(rdpMcs* mcs)
        int length = 12;
        s = transport_send_stream_init(mcs->transport, length);
 
-       mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ErectDomainRequest, length);
+       mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ErectDomainRequest, length, 0);
 
        per_write_integer(s, 0); /* subHeight (INTEGER) */
        per_write_integer(s, 0); /* subInterval (INTEGER) */
@@ -617,6 +636,25 @@ void mcs_send_erect_domain_request(rdpMcs* mcs)
 }
 
 /**
+ * Read MCS Attach User Request.\n
+ * @msdn{cc240524}
+ * @param mcs mcs module
+ * @param s stream
+ */
+
+boolean mcs_read_attach_user_request(rdpMcs* mcs, STREAM* s)
+{
+       int length;
+       enum DomainMCSPDU MCSPDU;
+
+       MCSPDU = DomainMCSPDU_AttachUserRequest;
+       if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length))
+               return False;
+
+       return True;
+}
+
+/**
  * Send MCS Attach User Request.\n
  * @msdn{cc240524}
  * @param mcs mcs module
@@ -628,7 +666,7 @@ void mcs_send_attach_user_request(rdpMcs* mcs)
        int length = 8;
        s = transport_send_stream_init(mcs->transport, length);
 
-       mcs_write_domain_mcspdu_header(s, DomainMCSPDU_AttachUserRequest, length);
+       mcs_write_domain_mcspdu_header(s, DomainMCSPDU_AttachUserRequest, length, 0);
 
        transport_write(mcs->transport, s);
 }
@@ -657,6 +695,30 @@ void mcs_recv_attach_user_confirm(rdpMcs* mcs)
 }
 
 /**
+ * Send MCS Attach User Confirm.\n
+ * @msdn{cc240525}
+ * @param mcs mcs module
+ */
+
+boolean mcs_send_attach_user_confirm(rdpMcs* mcs)
+{
+       STREAM* s;
+       int length = 11;
+       
+       s = transport_send_stream_init(mcs->transport, length);
+
+       mcs_write_domain_mcspdu_header(s, DomainMCSPDU_AttachUserConfirm, length, 2);
+
+       per_write_enumerated(s, 0, MCS_Result_enum_length); /* result */
+       mcs->user_id = 1002;
+       per_write_integer16(s, mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */
+
+       transport_write(mcs->transport, s);
+
+       return True;
+}
+
+/**
  * Send MCS Channel Join Request.\n
  * @msdn{cc240526}
  * @param mcs mcs module
@@ -669,7 +731,7 @@ void mcs_send_channel_join_request(rdpMcs* mcs, uint16 channel_id)
        int length = 12;
        s = transport_send_stream_init(mcs->transport, 12);
 
-       mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ChannelJoinRequest, length);
+       mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ChannelJoinRequest, length, 0);
 
        per_write_integer16(s, mcs->user_id, MCS_BASE_CHANNEL_ID);
        per_write_integer16(s, channel_id, 0);
index f8416a5..61141f3 100644 (file)
@@ -135,13 +135,16 @@ boolean mcs_read_connect_initial(rdpMcs* mcs, STREAM* s);
 void mcs_send_connect_initial(rdpMcs* mcs);
 void mcs_recv_connect_response(rdpMcs* mcs);
 boolean mcs_send_connect_response(rdpMcs* mcs);
+boolean mcs_read_erect_domain_request(rdpMcs* mcs, STREAM* s);
 void mcs_send_erect_domain_request(rdpMcs* mcs);
+boolean mcs_read_attach_user_request(rdpMcs* mcs, STREAM* s);
 void mcs_send_attach_user_request(rdpMcs* mcs);
 void mcs_recv_attach_user_confirm(rdpMcs* mcs);
+boolean mcs_send_attach_user_confirm(rdpMcs* mcs);
 void mcs_send_channel_join_request(rdpMcs* mcs, uint16 channel_id);
 void mcs_recv_channel_join_confirm(rdpMcs* mcs);
 boolean mcs_read_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU* domainMCSPDU, int* length);
-void mcs_write_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU domainMCSPDU, int length);
+void mcs_write_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU domainMCSPDU, int length, uint8 options);
 
 rdpMcs* mcs_new(rdpTransport* transport);
 void mcs_free(rdpMcs* mcs);
index 99022ba..3f6cfb1 100644 (file)
@@ -69,6 +69,16 @@ static int peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
                                return -1;
                        break;
 
+               case CONNECTION_STATE_MCS_CONNECT:
+                       if (!rdp_server_accept_mcs_erect_domain_request(peer->rdp, s))
+                               return -1;
+                       break;
+
+               case CONNECTION_STATE_MCS_ERECT_DOMAIN:
+                       if (!rdp_server_accept_mcs_attach_user_request(peer->rdp, s))
+                               return -1;
+                       break;
+
                default:
                        printf("Invalid state %d\n", peer->rdp->state);
                        return -1;
index 6cd2989..07d3eb5 100644 (file)
@@ -179,7 +179,7 @@ STREAM* rdp_data_pdu_init(rdpRdp* rdp)
 
 void rdp_write_header(rdpRdp* rdp, STREAM* s, int length, uint16 channel_id)
 {
-       mcs_write_domain_mcspdu_header(s, DomainMCSPDU_SendDataRequest, length);
+       mcs_write_domain_mcspdu_header(s, DomainMCSPDU_SendDataRequest, length, 0);
        per_write_integer16(s, rdp->mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator */
        per_write_integer16(s, channel_id, 0); /* channelId */
        stream_write_uint8(s, 0x70); /* dataPriority + segmentation */