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 }
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); } }
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; } } } }