Commits

Anonymous committed 12b6c8f

Checkpoint. Working toward raw channel I/O over TCP-mapped connections.

Comments (0)

Files changed (9)

 beep_core.cmo: beep_core.cmi 
 beep_core.cmx: beep_core.cmi 
+beep_serial.cmo: beep_core.cmi beep_serial.cmi 
+beep_serial.cmx: beep_core.cmx beep_serial.cmi 
 beep_core.cmo: beep_core.cmi 
 beep_core.cmx: beep_core.cmi 
+beep_serial.cmo: beep_core.cmi beep_serial.cmi 
+beep_serial.cmx: beep_core.cmx beep_serial.cmi 
 Open issues in development:
 
-...Redesigning from scratch.
-
-Central concepts of the BEEP core are the session, channel and exchange
-abstractions.  These are implemented as follows:
-
-SESSION: A driver for controlling one or more channels.  The first channel is
-the management channel, and its profile is defined by the BEEP specification
-and implemented internally.  A session agent is the engine that drives the
-session.  It sends the profile list to advertise.  It receives the profile list
-advertised by the peer.  It sends requests to open and close channels and
-receives the responses/errors.  It receives requests to open and close channels
-and sends the responses/errors.  It directs the session driver to bind and
-unbind channel drivers with channel agents.  The session driver is a virtual
-base class with derived classes to implement transport mappings.
-
-CHANNEL: A driver for sending and receiving messages and responses through a
-session on a particular channel.  The internal management channel is coupled
-tightly to the session driver.  A channel agent is the engine that drives the
-channel.  It may send exchanges and receive their responses.  It may receive
-exchanges and send their responses.  It may do both at the same time.  It
-receives notification of session layer errors.  The channel driver is a virtual
-base class with derived classes to implement transport mappings.
-
-EXCHANGE: A driver for sending and receiving MSG entities coupled with their
-RPY entity, ERR entity, ANS entity stream or NUL responses.  Each of the core
-exchanges defined for the management channel are implemented internally.  An
-exchange agent is the engine that drives the exchange, possibly through one or
-more layers of message processors.  An exchange driver operates at the layer of
-MIME entity stream content of the five BEEP core types, i.e. MSG, RPY, ERR, ANS
-and NUL, coupled tightly with the channel driver.
-
-
-+ (Beep_core)
-    Every BEEP message exchange, channel agent and  session agent is a stream
-    engine gadget.
-    
-    Session agents send and receive channel management message exchanges and
-    start/stop channel agents accordingly.  Channel agents send and receive
-    profile-specific message exchanges (the session management channel has a
-    profile defined in the BEEP core).
-    
-    The client message exchange renders a single Mime_stream emitter event on
-    its output jack and ingests a single Beep_core.response_scanner on its
-    input jack.  Channel agents send client message exchanges on their output
-    jacks.
-    
-    The service message exchange ingests a single Mime_stream.entity_scanner
-    on its input jack and renders a single Beep_core.response_emitter on its
-    output jack.  Channel agents receive service message exchanges on their
-    input jacks.
-
 # End of open issues

beep/beep_core.ml

 
 (*--- errors ---*)
 type error =
+    | X_session_aborted
+    | X_transport_error of exn
     | X_frame_bad_syntax
     | X_frame_too_large
     | X_frame_out_of_sequence of header
         header.seqno
 
 let error_to_string = function
+    | X_session_aborted -> "session aborted"
+    | X_transport_error x ->
+        Printf.sprintf "transport error [%s]" (Printexc.to_string x)
     | X_frame_bad_syntax -> "bad frame syntax"
     | X_frame_too_large -> "frame too large"
     | X_frame_out_of_sequence h -> sprintf_header "frame out of sequence" h
 
 (*--- frame format and parsing ---*)
 let parse_frame =
+    let bad_syntax = Error X_frame_bad_syntax in
+    let too_large = Error X_frame_too_large in
+    let ef _ x = raise (match x with End_of_file -> x | _ -> bad_syntax) in
     let module K = struct type t = MSG | RPY | ERR | ANS | NUL end in
-    let ef_ _ x =
-    	raise begin
-            match x with
-            | End_of_file -> x
-            | _ -> Error X_frame_bad_syntax
-        end
-    in
-    let keyword_ s =
-    	Scanf.kscanf s ef_ "%3[A-Z]" begin function
+    let keyword s =
+    	Scanf.kscanf s ef "%3[A-Z]" begin function
     		| "MSG" -> K.MSG
     		| "RPY" -> K.RPY
     		| "ERR" -> K.ERR
     		| "ANS" -> K.ANS
     		| "NUL" -> K.NUL
-    		| _ -> raise (Error X_frame_bad_syntax)
+    		| _ -> raise bad_syntax
     	end
     in
-    let uint31_ n =
-    	if Int32.compare n 0l < 0 then
-    		raise (Error X_frame_bad_syntax)
-    in
-    let more_ v =
+    let uint31 n = if Int32.compare n 0l < 0 then raise bad_syntax in
+    let more v =
     	match String.unsafe_get v 0 with
     	| '.' -> Iom_stream.Last
     	| _ -> Iom_stream.More
     in
-    let int32_of_maxint_ = Int32.of_int max_int in
-    let size_ ?limit v =
-    	uint31_ v;
+    let int32_of_maxint = Int32.of_int max_int in
+    let size ?limit v =
+    	uint31 v;
     	match limit with
-    	| Some limit when Int32.compare v limit > 0 ->
-    		raise (Error X_frame_too_large)
-    	| _ when Int32.compare v int32_of_maxint_ > 0 ->
-    		raise (Error X_frame_too_large)
-    	| _ ->
-    		Int32.to_int v
+    	| Some limit when Int32.compare v limit > 0 -> raise too_large
+    	| _ when Int32.compare v int32_of_maxint > 0 -> raise too_large
+    	| _ -> Int32.to_int v
     in
-    let common_ ?limit s =
-    	Scanf.kscanf s ef_ " %lu %lu %[.*] %lu %lu"
+    let common ?limit s =
+    	Scanf.kscanf s ef " %lu %lu %[.*] %lu %lu"
     	begin fun a b c d e ->
-    		uint31_ a;
-    		uint31_ b;
-    		let c = more_ c in
-    		let e = size_ ?limit e in
+    		uint31 a;
+    		uint31 b;
+    		let c = more c in
+    		let e = size ?limit e in
     		{ channo = a; msgno = b; seqno = d }, c, e
     	end
     in
-    let crlf_ s = Scanf.kscanf s ef_ "\r\n%n" (fun x -> x) in
-    let payload_ more m hlen size =
+    let crlf s = Scanf.kscanf s ef "\r\n%n" (fun x -> x) in
+    let payload more m hlen size =
     	let mlen = Cf_message.length m in
     	if mlen < hlen + size + 5 then raise End_of_file;
     	let m = Cf_message.shift ~pos:hlen m in
     	let data, m = Cf_message.split ~pos:size m in
     	let trailer, m = Cf_message.split ~pos:5 m in
-    	if Cf_message.contents trailer <> "END\r\n" then
-    		raise (Error X_frame_bad_syntax);
+    	if Cf_message.contents trailer <> "END\r\n" then raise bad_syntax;
     	more, data, m
     in
-    let single_ ?limit s m =
-    	let header, more, size = common_ ?limit s in
-    	let hlen = crlf_ s in
-    	let more, data, m = payload_ more m hlen size in
+    let single ?limit s m =
+    	let header, more, size = common ?limit s in
+    	let hlen = crlf s in
+    	let more, data, m = payload more m hlen size in
     	(header, more, data), m
     in
     fun ?limit m ->
     	let s = Scanf.Scanning.from_function (Cf_message.to_function m) in
-    	match keyword_ s with
+    	match keyword s with
     	| K.MSG ->
-    		let hd, tl = single_ ?limit s m in (`MSG hd), tl
+    		let hd, tl = single ?limit s m in (`MSG hd), tl
     	| K.RPY ->
-    		let hd, tl = single_ ?limit s m in (`RPY hd), tl
+    		let hd, tl = single ?limit s m in (`RPY hd), tl
     	| K.ERR ->
-    		let hd, tl = single_ ?limit s m in (`ERR hd), tl
+    		let hd, tl = single ?limit s m in (`ERR hd), tl
     	| K.ANS ->
-    		let header, more, size = common_ ?limit s in
-    		let ansno = Scanf.kscanf s ef_ " %lu" (fun x -> uint31_ x; x) in
-    		let hlen = crlf_ s in
-    		let more, data, m = payload_ more m hlen size in
+    		let header, more, size = common ?limit s in
+    		let ansno = Scanf.kscanf s ef " %lu" (fun x -> uint31 x; x) in
+    		let hlen = crlf s in
+    		let more, data, m = payload more m hlen size in
     		`ANS (ansno, header, more, data), m
     	| K.NUL ->
-    		Scanf.kscanf s ef_ " %lu %lu . %lu 0\r\nEND\r\n%n"
+    		Scanf.kscanf s ef " %lu %lu . %lu 0\r\nEND\r\n%n"
     		begin fun a b c n ->
-    			uint31_ a;
-    			uint31_ b;
+    			uint31 a;
+    			uint31 b;
     			let header = { channo = a; msgno = b; seqno = c } in
     			let m = Cf_message.shift ~pos:n m in
     			(`NUL header), m
     		end
 
 let emit_frame =
-    let trailer_ = [ "END\r\n", 0, 5 ] in
-    let common_ b header more size =
+    let trailer = [ "END\r\n", 0, 5 ] in
+    let common b header more size =
     	let more = match more with Iom_stream.More -> '*' | _ -> '.' in
     	Printf.bprintf b " %lu %lu %c %lu %u" header.channo header.msgno more
     		header.seqno size
     in
-    let payload_ b m =
+    let payload b m =
     	Buffer.add_string b "\r\n";
     	let hlen = Buffer.length b in
-    	(Buffer.contents b, 0, hlen) :: (m @ trailer_)
+    	(Buffer.contents b, 0, hlen) :: (m @ trailer)
     in
-    let single_ keyword header more m =
+    let single keyword header more m =
     	let b = Buffer.create 40 in
     	Buffer.add_string b keyword;
     	let size = Cf_message.length m in
-    	common_ b header more size;
-    	payload_ b m
+    	common b header more size;
+    	payload b m
     in
     function
     | `MSG (header, more, data) ->
-    	single_ "MSG" header more data
+    	single "MSG" header more data
     | `RPY (header, more, data) ->
-    	single_ "RPY" header more data
+    	single "RPY" header more data
     | `ERR (header, more, data) ->
-    	single_ "ERR" header more data
+    	single "ERR" header more data
     | `ANS (ansno, header, more, data) ->
     	let b = Buffer.create 40 in
     	Buffer.add_string b "ANS";
     	let size = Cf_message.length data in
-    	common_ b header more size;
+    	common b header more size;
     	Printf.bprintf b " %lu" ansno;
-    	payload_ b data
+    	payload b data
     | `NUL header ->
     	let b = Buffer.create 40 in
     	Buffer.add_string b "NUL";
     method limits = limits_
 end
 
-type eijack = {
-    eij_flowTx: Iom_stream.readywait Iom_gadget.tx;
-    eij_eventRx: Mime_stream.entity_scan_event Iom_gadget.rx;
+type iefix = {
+    ief_flowTx: Iom_stream.readywait Iom_gadget.tx;
+    ief_eventRx: Mime_stream.entity_scan_event Iom_gadget.rx;
 }
 
-type eiplug = {
-    eip_flowRx: Iom_stream.readywait Iom_gadget.rx;
-    eip_eventTx: Mime_stream.entity_scan_event Iom_gadget.tx;
-    eip_limits: Iom_octet_stream.limits;
+type iepad = {
+    iep_flowRx: Iom_stream.readywait Iom_gadget.rx;
+    iep_eventTx: Mime_stream.entity_scan_event Iom_gadget.tx;
+    iep_limits: Iom_octet_stream.limits;
 }
 
-type eis_variant =
-    | S_ei_body of Iom_octet_stream.fragment Iom_gadget.tx
-    | S_ei_header
-    | S_ei_failed
+type ies_variant =
+    | S_iev_body of Iom_octet_stream.fragment Iom_gadget.tx
+    | S_iev_header
+    | S_iev_failed
 
-type eistate = {
-    eis_ready: bool;
-    eis_more: Iom_stream.more;
-    eis_buffer: Cf_message.substring Cf_deque.t;
-    eis_length: int;
-    eis_variant: eis_variant;
+type iestate = {
+    ies_ready: bool;
+    ies_more: Iom_stream.more;
+    ies_buffer: Cf_message.substring Cf_deque.t;
+    ies_length: int;
+    ies_variant: ies_variant;
 }
 
-let ei_state0 = {
-    eis_ready = false;
-    eis_more = Iom_stream.More;
-    eis_buffer = Cf_deque.nil;
-    eis_length = 0;
-    eis_variant = S_ei_header;
+let ies0 = {
+    ies_ready = false;
+    ies_more = Iom_stream.More;
+    ies_buffer = Cf_deque.nil;
+    ies_length = 0;
+    ies_variant = S_iev_header;
 }
 
-let ei_harness limits =
+let ie_harness limits =
     Iom_gadget.duplex >>= fun ((flowRx, eventTx), (eventRx, flowTx)) ->
-    let eip = {
-        eip_flowRx = flowRx;
-        eip_eventTx = eventTx;
-        eip_limits = limits;
+    let iep = {
+        iep_flowRx = flowRx;
+        iep_eventTx = eventTx;
+        iep_limits = limits;
     } in
-    let eij = {
-        eij_flowTx = flowTx;
-        eij_eventRx = eventRx;
+    let ief = {
+        ief_flowTx = flowTx;
+        ief_eventRx = eventRx;
     } in
-    Cf_cmonad.return (eip, eij)
+    Cf_cmonad.return (iep, ief)
 
-let ei_failed eis failedTx x =
+let ie_failed ies failedTx x =
     let failedTx = (failedTx :> Iom_stream.failed Iom_gadget.tx) in
     failedTx#put (`Failed x) >>= fun () ->
-    Cf_cmonad.return (0, Some { eis with eis_variant = S_ei_failed })
+    Cf_cmonad.return (0, Some { ies with ies_variant = S_iev_failed })
 
-let ei_push eis more buffer length =
-    let eis = {
-        eis with
-        eis_more = more;
-        eis_buffer = buffer;
-        eis_length = length;
+let ie_push ies more buffer length =
+    let ies = {
+        ies with
+        ies_more = more;
+        ies_buffer = buffer;
+        ies_length = length;
     } in
-    Cf_cmonad.return (0, Some eis)
+    Cf_cmonad.return (0, Some ies)
 
-let ei_drain eis fragmentTx more buffer =
+let ie_drain ies fragmentTx more buffer =
     let data = Cf_message.drain buffer in
     let length = Cf_message.length data in
     let fragment = new Iom_octet_stream.fragment more data in
     fragmentTx#put fragment >>= fun () ->
-    let eisopt =
+    let iesopt =
         match more with
         | Iom_stream.Last ->
             None
         | Iom_stream.More ->
             Some {
-                eis with
-                eis_ready = true;
-                eis_buffer = Cf_deque.nil;
-                eis_length = 0;
+                ies with
+                ies_ready = true;
+                ies_buffer = Cf_deque.nil;
+                ies_length = 0;
             }
     in
-    Cf_cmonad.return (length, eisopt)
+    Cf_cmonad.return (length, iesopt)
 
-let ei_body eis eip fragmentTx more buffer length =
-    if not eis.eis_ready || length < eip.eip_limits.Iom_octet_stream.low then
-        ei_push eis more buffer length
+let ie_body ies iep fragmentTx more buffer length =
+    if not ies.ies_ready || length < iep.iep_limits.Iom_octet_stream.low then
+        ie_push ies more buffer length
     else
-        ei_drain eis fragmentTx more buffer
+        ie_drain ies fragmentTx more buffer
 
-let ei_headers eis eip failedTx more buffer length =
+let ie_headers ies iep failedTx more buffer length =
     let data = Cf_message.drain buffer in
     match
         try
     with
     | Cf_exnopt.U (scanner, body) ->
         Iom_gadget.simplex >>= fun (fragmentRx, fragmentTx) ->
-        eip.eip_eventTx#put (scanner, fragmentRx) >>= fun () ->
+        iep.iep_eventTx#put (scanner, fragmentRx) >>= fun () ->
         let length = Cf_message.length body in
         let buffer = Cf_message.push body Cf_deque.nil in
-        ei_body eis eip fragmentTx more buffer length
+        ie_body ies iep fragmentTx more buffer length
     | Cf_exnopt.X End_of_file ->
         if more = Iom_stream.Last then begin
             let x = Mime_stream.Scan_error Mime_stream.X_header_incomplete in
-            ei_failed eis failedTx x
+            ie_failed ies failedTx x
         end
-        else if length < eip.eip_limits.Iom_octet_stream.high then begin
+        else if length < iep.iep_limits.Iom_octet_stream.high then begin
             let x = Mime_stream.Scan_error Mime_stream.X_header_too_long in
-            ei_failed eis failedTx x
+            ie_failed ies failedTx x
         end
         else
-            ei_push eis more buffer length
+            ie_push ies more buffer length
     | Cf_exnopt.X x ->
-        ei_failed eis failedTx x
+        ie_failed ies failedTx x
 
-let ei_frame eis eip failedTx more data =
-    let length = eis.eis_length + (Cf_message.length data) in
-    match eis.eis_variant with
-    | S_ei_failed ->
-        let eisopt = match more with Iom_stream.More -> Some eis | _ -> None in
-        Cf_cmonad.return (length, eisopt)
+let ie_frame ies iep failedTx more data =
+    let length = ies.ies_length + (Cf_message.length data) in
+    match ies.ies_variant with
+    | S_iev_failed ->
+        let iesopt = match more with Iom_stream.More -> Some ies | _ -> None in
+        Cf_cmonad.return (length, iesopt)
     | _ ->
-        let buffer = Cf_message.push data eis.eis_buffer in
-        match eis.eis_variant with
-        | S_ei_body fragmentTx when eis.eis_ready ->
-            ei_body eis eip fragmentTx more buffer length
-        | S_ei_header when eis.eis_ready ->
-            ei_headers eis eip failedTx more buffer length
+        let buffer = Cf_message.push data ies.ies_buffer in
+        match ies.ies_variant with
+        | S_iev_body fragmentTx when ies.ies_ready ->
+            ie_body ies iep fragmentTx more buffer length
+        | S_iev_header when ies.ies_ready ->
+            ie_headers ies iep failedTx more buffer length
         | _ ->
-            ei_push eis more buffer length
+            ie_push ies more buffer length
 
-let ei_flow_guard eis eip cont =
-    eip.eip_flowRx#get begin function
-        | `Wait when eis.eis_ready ->
-            cont (0, Some { eis with eis_ready = false })
-        | `Ready when not eis.eis_ready ->
-            begin match eis.eis_variant with
-            | S_ei_body fragmentTx when eis.eis_length > 0 ->
-                ei_drain eis fragmentTx eis.eis_more eis.eis_buffer >>= cont
+let ie_flow_guard ies iep cont =
+    iep.iep_flowRx#get begin function
+        | `Wait when ies.ies_ready ->
+            cont (0, Some { ies with ies_ready = false })
+        | `Ready when not ies.ies_ready ->
+            begin match ies.ies_variant with
+            | S_iev_body fragmentTx when ies.ies_length > 0 ->
+                ie_drain ies fragmentTx ies.ies_more ies.ies_buffer >>= cont
             | _ ->
-                cont (0, Some { eis with eis_ready = true })
+                cont (0, Some { ies with ies_ready = true })
             end
         | `Ready
         | `Wait ->
-            cont (0, Some eis)
+            cont (0, Some ies)
     end
 
-type eojack = {
-    eoj_flowRx: Iom_stream.readywait Iom_gadget.rx;
-    eoj_eventTx: Mime_stream.entity_emit_event Iom_gadget.tx;
+type oefix = {
+    oef_flowRx: Iom_stream.readywait Iom_gadget.rx;
+    oef_eventTx: Mime_stream.entity_emit_event Iom_gadget.tx;
 }
 
-type eoplug = {
-    eop_flowTx: Iom_stream.readywait Iom_gadget.tx;
-    eop_eventRx: Mime_stream.entity_emit_event Iom_gadget.rx;
-    eop_limits: Iom_octet_stream.limits;
+type oepad = {
+    oep_flowTx: Iom_stream.readywait Iom_gadget.tx;
+    oep_eventRx: Mime_stream.entity_emit_event Iom_gadget.rx;
+    oep_limits: Iom_octet_stream.limits;
 }
 
-type eos_variant =
-    | S_eo_body of Iom_octet_stream.fragment Iom_gadget.rx
-    | S_eo_header
+type oes_variant =
+    | S_oev_body of Iom_octet_stream.fragment Iom_gadget.rx
+    | S_oev_header
 
-type eostate = {
-    eos_ready: bool;
-    eos_more: Iom_stream.more;
-    eos_buffer: Cf_message.substring Cf_deque.t;
-    eos_length: int;
-    eos_variant: eos_variant;
+type oestate = {
+    oes_ready: bool;
+    oes_more: Iom_stream.more;
+    oes_buffer: Cf_message.substring Cf_deque.t;
+    oes_length: int;
+    oes_variant: oes_variant;
 }
 
-let eo_state0 = {
-    eos_ready = false;
-    eos_more = Iom_stream.More;
-    eos_buffer = Cf_deque.nil;
-    eos_length = 0;
-    eos_variant = S_eo_header;
+let oes0 = {
+    oes_ready = false;
+    oes_more = Iom_stream.More;
+    oes_buffer = Cf_deque.nil;
+    oes_length = 0;
+    oes_variant = S_oev_header;
 }
 
-let eo_harness limits =
+let oe_harness limits =
     Iom_gadget.duplex >>= fun ((eventRx, flowTx), (flowRx, eventTx)) ->
-    let eop = {
-        eop_flowTx = flowTx;
-        eop_eventRx = eventRx;
-        eop_limits = limits;
+    let oep = {
+        oep_flowTx = flowTx;
+        oep_eventRx = eventRx;
+        oep_limits = limits;
     } in
-    let eoj = {
-        eoj_flowRx = flowRx;
-        eoj_eventTx = eventTx;
+    let oef = {
+        oef_flowRx = flowRx;
+        oef_eventTx = eventTx;
     } in
-    Cf_cmonad.return (eop, eoj)
+    Cf_cmonad.return (oep, oef)
 
-let eo_work window eos eop more buffer length =
+let oe_work window oes oep more buffer length =
     match more with
-    | _ when window < eop.eop_limits.Iom_octet_stream.low && eos.eos_ready ->
-        let eos = {
-            eos with
-            eos_ready = false;
-            eos_more = more;
-            eos_buffer = buffer;
-            eos_length = length;
+    | Iom_stream.More
+      when window < oep.oep_limits.Iom_octet_stream.low && oes.oes_ready ->
+        let oes = {
+            oes with
+            oes_ready = false;
+            oes_more = more;
+            oes_buffer = buffer;
+            oes_length = length;
         } in
-        eop.eop_flowTx#put `Wait >>= fun () ->
-        Cf_cmonad.return (Some eos, None)
-    | _ when window < eop.eop_limits.Iom_octet_stream.low ->
-        let eos = {
-            eos with
-            eos_buffer = buffer;
-            eos_length = length;
+        oep.oep_flowTx#put `Wait >>= fun () ->
+        Cf_cmonad.return (Some oes, None)
+    | _ when window < oep.oep_limits.Iom_octet_stream.low ->
+        let oes = {
+            oes with
+            oes_more = more;
+            oes_buffer = buffer;
+            oes_length = length;
         } in
-        Cf_cmonad.return (Some eos, None)
+        Cf_cmonad.return (Some oes, None)
     | Iom_stream.Last when length > window ->
         let payload, buffer = Cf_message.pop ~len:window buffer in
         let length = length - window in
-        let eos = {
-            eos with
-            eos_ready = false;
-            eos_more = more;
-            eos_buffer = buffer;
-            eos_length = length;
+        let oes = {
+            oes with
+            oes_ready = false;
+            oes_more = more;
+            oes_buffer = buffer;
+            oes_length = length;
         } in
-        Cf_cmonad.return (Some eos, Some (window, Iom_stream.More, payload))
+        Cf_cmonad.return (Some oes, Some (window, Iom_stream.More, payload))
     | Iom_stream.Last ->
         Cf_cmonad.return (None, Some (length, more, Cf_message.drain buffer))
     | Iom_stream.More ->
         let limit =
-            if window > eop.eop_limits.Iom_octet_stream.high then
-                eop.eop_limits.Iom_octet_stream.high
+            if window > oep.oep_limits.Iom_octet_stream.high then
+                oep.oep_limits.Iom_octet_stream.high
             else
                 window
         in
         if length > limit then begin
             let payload, buffer = Cf_message.pop ~len:window buffer in
             let length = length - limit in
-            let eos = {
-                eos with
-                eos_ready = false;
-                eos_more = more;
-                eos_buffer = buffer;
-                eos_length = length;
+            let oes = {
+                oes with
+                oes_ready = false;
+                oes_more = more;
+                oes_buffer = buffer;
+                oes_length = length;
             } in
-            let rv = (Some eos, Some (limit, Iom_stream.More, payload)) in
-            eop.eop_flowTx#put `Wait >>= fun () ->
+            let rv = (Some oes, Some (limit, Iom_stream.More, payload)) in
+            oep.oep_flowTx#put `Wait >>= fun () ->
             Cf_cmonad.return rv
         end
         else begin
             let payload = Cf_message.drain buffer in
             let length = Cf_message.length payload in
-            let waiting = not eos.eos_ready in
-            let eos = {
-                eos with
-                eos_ready = true;
-                eos_buffer = Cf_deque.nil;
-                eos_length = 0;
+            let waiting = not oes.oes_ready in
+            let oes = {
+                oes with
+                oes_ready = true;
+                oes_buffer = Cf_deque.nil;
+                oes_length = 0;
             } in
-            let result = Some eos, Some (length, more, payload) in
+            let result = Some oes, Some (length, more, payload) in
             if waiting then begin
-                eop.eop_flowTx#put `Ready >>= fun () ->
+                oep.oep_flowTx#put `Ready >>= fun () ->
                 Cf_cmonad.return result
             end
             else
                 Cf_cmonad.return result
         end
 
-let eo_ready window eos eop =
-    eo_work window eos eop eos.eos_more eos.eos_buffer eos.eos_length
+let oe_ready window oes oep =
+    oe_work window oes oep oes.oes_more oes.oes_buffer oes.oes_length
 
-let eo_event_guard window eos eop cont =
-    match eos.eos_variant with
-    | S_eo_header ->
-        eop.eop_eventRx#get begin fun (headers, fragmentRx) ->
+let oe_event_guard window oes oep cont =
+    match oes.oes_variant with
+    | S_oev_header ->
+        oep.oep_eventRx#get begin fun (headers, fragmentRx) ->
             let data = headers#emit in
-            let buffer = Cf_message.push data eos.eos_buffer in
-            let length = eos.eos_length + Cf_message.length data in
-            assert (eos.eos_more == Iom_stream.More);
-            let eos = {
-                eos with
-                eos_ready = true;
-                eos_buffer = buffer;
-                eos_length = length;
-                eos_variant = S_eo_body fragmentRx;
+            let buffer = Cf_message.push data oes.oes_buffer in
+            let length = oes.oes_length + Cf_message.length data in
+            assert (oes.oes_more == Iom_stream.More);
+            let oes = {
+                oes with
+                oes_ready = true;
+                oes_buffer = buffer;
+                oes_length = length;
+                oes_variant = S_oev_body fragmentRx;
             } in
-            let v = Some eos, None in
+            let v = Some oes, None in
             if window < length then
                 cont v
             else begin
-                eop.eop_flowTx#put `Ready >>= fun () ->
+                oep.oep_flowTx#put `Ready >>= fun () ->
                 cont v
             end
         end
-    | S_eo_body fragmentRx ->
+    | S_oev_body fragmentRx ->
         fragmentRx#get begin fun fragment ->
             let data = fragment#data in
-            let buffer = Cf_message.push data eos.eos_buffer in
-            let length = eos.eos_length + Cf_message.length data in
-            eo_work window eos eop fragment#more buffer length >>= cont
+            let buffer = Cf_message.push data oes.oes_buffer in
+            let length = oes.oes_length + Cf_message.length data in
+            oe_work window oes oep fragment#more buffer length >>= cont
         end
 
 (*--- exchange I/O ---*)
-class ['msg, 'rpy, 'err, 'ans] cprofile ~msg ~rpy ~err ~ans = object
+class ['msg, 'rpy, 'err, 'ans] chprofile ~msg ~rpy ~err ~ans = object
     constraint 'msg = #eprofile
     constraint 'rpy = #eprofile
     constraint 'err = #eprofile
 end
 
 type sxrsp =
-    | M_srv_rpy of eoplug
-    | M_srv_err of eoplug
-    | M_srv_ans of int32 * eoplug
+    | M_srv_rpy of oepad
+    | M_srv_err of oepad
+    | M_srv_ans of int32 * oepad
     | M_srv_nul
 
-type sxplug = {
+type sxpad = {
     sxp_msgno: int32;
-    sxp_req: eiplug;
+    sxp_req: iepad;
     sxp_rspRx: sxrsp Iom_gadget.rx;
     sxp_failedTx: Iom_stream.failed Iom_gadget.tx;
 }
 
-type sxjack = {
-    sxj_msgno: int32;
-    sxj_req: eijack;
-    sxj_rspTx: sxrsp Iom_gadget.tx;
-    sxj_failedRx: Iom_stream.failed Iom_gadget.rx;
+type sxfix = {
+    sxf_msgno: int32;
+    sxf_req: iefix;
+    sxf_rspTx: sxrsp Iom_gadget.tx;
+    sxf_failedRx: Iom_stream.failed Iom_gadget.rx;
 }
 
 let sx_harness ep msgno =
     Iom_gadget.duplex >>= fun ((rspRx, failedTx), (failedRx, rspTx)) ->
-    ei_harness ep#limits >>= fun (eip, eij) ->
+    ie_harness ep#limits >>= fun (iep, ief) ->
     let sxp = {
         sxp_msgno = msgno;
-        sxp_req = eip;
+        sxp_req = iep;
         sxp_rspRx = rspRx;
         sxp_failedTx = failedTx;
     } in
-    let sxj = {
-        sxj_msgno = msgno;
-        sxj_req = eij;
-        sxj_rspTx = rspTx;
-        sxj_failedRx = failedRx;
+    let sxf = {
+        sxf_msgno = msgno;
+        sxf_req = ief;
+        sxf_rspTx = rspTx;
+        sxf_failedRx = failedRx;
     } in
-    Cf_cmonad.return (sxp, sxj)
+    Cf_cmonad.return (sxp, sxf)
 
 let sx_msgno_check header sxp = (Int32.compare header.msgno sxp.sxp_msgno = 0)
 let sx_msgno_check_queue header = Cf_deque.predicate (sx_msgno_check header)
 
 type cxrsp =
-    | M_clt_rpy of eijack
-    | M_clt_err of eijack
-    | M_clt_ans of int32 * eijack
+    | M_clt_rpy of iefix
+    | M_clt_err of iefix
+    | M_clt_ans of int32 * iefix
     | M_clt_nul
 
-type cxplug = {
+type cxpad = {
     cxp_msgno: int32;
-    cxp_req: eoplug;
+    cxp_req: oepad;
     cxp_rspTx: cxrsp Iom_gadget.tx;
     cxp_failedTx: Iom_stream.failed Iom_gadget.tx;
 }
     
-type cxjack = {
-    cxj_msgno: int32;
-    cxj_req: eojack;
-    cxj_rspRx: cxrsp Iom_gadget.rx;
-    cxj_failedRx: Iom_stream.failed Iom_gadget.rx;
+type cxfix = {
+    cxf_msgno: int32;
+    cxf_req: oefix;
+    cxf_rspRx: cxrsp Iom_gadget.rx;
+    cxf_failedRx: Iom_stream.failed Iom_gadget.rx;
 }
 
 let cx_harness profile msgno =
     Iom_gadget.duplex >>= fun ((failedRx, rspTx), (rspRx, failedTx)) ->
-    eo_harness profile#msg#limits >>= fun (eop, eoj) ->
+    oe_harness profile#msg#limits >>= fun (oep, oef) ->
     let cxp = {
         cxp_msgno = msgno;
-        cxp_req = eop;
+        cxp_req = oep;
         cxp_rspTx = rspTx;
         cxp_failedTx = failedTx;
     } in
-    let cxj = {
-        cxj_msgno = msgno;
-        cxj_req = eoj;
-        cxj_rspRx = rspRx;
-        cxj_failedRx = failedRx;
+    let cxf = {
+        cxf_msgno = msgno;
+        cxf_req = oef;
+        cxf_rspRx = rspRx;
+        cxf_failedRx = failedRx;
     } in
-    Cf_cmonad.return (cxp, cxj)
+    Cf_cmonad.return (cxp, cxf)
 
 let cx_msgno_check header cxp = (Int32.compare header.msgno cxp.cxp_msgno = 0)
 let cx_msgno_check_queue header = Cf_deque.predicate (cx_msgno_check header)
 
-type mrxvariant =
+type chsrxvariant =
     | S_mrx_new
-    | S_mrx_msg of sxplug * eistate
-    | S_mrx_rpy of cxplug * eiplug * eistate
-    | S_mrx_err of cxplug * eiplug * eistate
-    | S_mrx_ans of cxplug * (eiplug * eistate) N32_map.t
+    | S_mrx_msg of sxpad * iestate
+    | S_mrx_rpy of cxpad * iepad * iestate
+    | S_mrx_err of cxpad * iepad * iestate
+    | S_mrx_ans of cxpad * (iepad * iestate) N32_map.t
 
 let mrx_failed mrx x =
     match mrx with
     | S_mrx_msg (sxp, _) ->
         sxp.sxp_failedTx#put x
 
-type mtxvariant =
+type chstxvariant =
     | S_mtx_new
-    | S_mtx_msg of cxplug * eostate
-    | S_mtx_rpy of sxplug * eoplug * eostate
-    | S_mtx_err of sxplug * eoplug * eostate
+    | S_mtx_msg of cxpad * oestate
+    | S_mtx_rpy of sxpad * oepad * oestate
+    | S_mtx_err of sxpad * oepad * oestate
     | S_mtx_ans of
-        sxplug * (eoplug * eostate) N32_map.t * (int32 * eoplug) Cf_deque.t *
+        sxpad * (oepad * oestate) N32_map.t * (int32 * oepad) Cf_deque.t *
         Iom_stream.more
 
 let mtx_failed mtx x =
         cxp.cxp_failedTx#put x
 
 (*--- channel I/O ---*)
-class type cprofile_basic = [eprofile, eprofile, eprofile, eprofile] cprofile
+class type chprofile_basic = [eprofile, eprofile, eprofile, eprofile] chprofile
 
-type cnotify = Iom_stream.failed
+type chnotify = Iom_stream.failed
 
-type cplug = {
-    cp_channo: int32;
-    cp_profile: cprofile_basic;
-    cp_notifyTx: cnotify Iom_gadget.tx;
-    cp_exchangeRx: cxplug Iom_gadget.rx;
-    cp_exchangeTx: sxjack Iom_gadget.tx;
+type chpad = {
+    chp_channo: int32;
+    chp_profile: chprofile_basic;
+    chp_notifyTx: chnotify Iom_gadget.tx;
+    chp_exchangeRx: cxpad Iom_gadget.rx;
+    chp_exchangeTx: sxfix Iom_gadget.tx;
 }
 
-type cjack = {
-    cj_notifyRx: cnotify Iom_gadget.rx;
-    cj_exchangeRx: sxjack Iom_gadget.rx;
-    cj_exchangeTx: cxplug Iom_gadget.tx;
+type chfix = {
+    chf_notifyRx: chnotify Iom_gadget.rx;
+    chf_exchangeRx: sxfix Iom_gadget.rx;
+    chf_exchangeTx: cxpad Iom_gadget.tx;
 }
 
-let c_harness channo profile =
-    let profile = (profile :> cprofile_basic) in
+let ch_harness channo profile =
+    let profile = (profile :> chprofile_basic) in
     Iom_gadget.duplex >>= fun ((upRx, dnTx), (dnRx, upTx)) ->
     Iom_gadget.simplex >>= fun (notifyRx, notifyTx) ->
-    let cp = {
-        cp_channo = channo;
-        cp_profile = profile;
-        cp_notifyTx = notifyTx;
-        cp_exchangeRx = dnRx;
-        cp_exchangeTx = upTx;
+    let chp = {
+        chp_channo = channo;
+        chp_profile = profile;
+        chp_notifyTx = notifyTx;
+        chp_exchangeRx = dnRx;
+        chp_exchangeTx = upTx;
     } in
-    let cj = {
-        cj_notifyRx = notifyRx;
-        cj_exchangeRx = upRx;
-        cj_exchangeTx = dnTx;
+    let chf = {
+        chf_notifyRx = notifyRx;
+        chf_exchangeRx = upRx;
+        chf_exchangeTx = dnTx;
     } in
-    Cf_cmonad.return (cp, cj)
+    Cf_cmonad.return (chp, chf)
 
-type cstate = {
-    cs_rxseqno: int32;
-    cs_rxv: mrxvariant;
-    cs_rxq: cxplug Cf_deque.t;
-    cs_txseqno: int32;
-    cs_txv: mtxvariant;
-    cs_txq: sxplug Cf_deque.t;
+type chstate = {
+    chs_rxseqno: int32;
+    chs_rxv: chsrxvariant;
+    chs_rxq: cxpad Cf_deque.t;
+    chs_txseqno: int32;
+    chs_txv: chstxvariant;
+    chs_txq: sxpad Cf_deque.t;
 }
 
-let cstate0 = {
-    cs_rxseqno = 0l;
-    cs_rxv = S_mrx_new;
-    cs_rxq = Cf_deque.nil;
-    cs_txseqno = 0l;
-    cs_txv = S_mtx_new;
-    cs_txq = Cf_deque.nil;
+let chs0 = {
+    chs_rxseqno = 0l;
+    chs_rxv = S_mrx_new;
+    chs_rxq = Cf_deque.nil;
+    chs_txseqno = 0l;
+    chs_txv = S_mtx_new;
+    chs_txq = Cf_deque.nil;
 }
 
-let c_failed cs cp error =
+let ch_failed chs chp error =
     let x = Error error in
     let fx = `Failed x in
-    cp.cp_notifyTx#put fx >>= fun () ->
-    mrx_failed cs.cs_rxv fx >>= fun () ->
-    let z = Cf_deque.B.to_seq cs.cs_rxq in
+    chp.chp_notifyTx#put fx >>= fun () ->
+    mrx_failed chs.chs_rxv fx >>= fun () ->
+    let z = Cf_deque.B.to_seq chs.chs_rxq in
     let z = Cf_seq.map (fun cxp -> cxp.cxp_failedTx#put fx) z in
     Cf_seq.C.sequence z >>= fun () ->
-    mtx_failed cs.cs_txv fx >>= fun () ->
-    let z = Cf_deque.B.to_seq cs.cs_txq in
+    mtx_failed chs.chs_txv fx >>= fun () ->
+    let z = Cf_deque.B.to_seq chs.chs_txq in
     let z = Cf_seq.map (fun sxp -> sxp.sxp_failedTx#put fx) z in
     Cf_seq.C.sequence z >>= fun () ->
     Cf_cmonad.return (Cf_exnopt.X x)
 
-let c_rxframe_header cs cp header =
-    if Int32.compare cp.cp_channo header.channo <> 0 then
+let ch_rxf_header chs chp header =
+    if Int32.compare chp.chp_channo header.channo <> 0 then
         Some (X_frame_no_channel header)
-    else if Int32.compare cs.cs_rxseqno header.seqno <> 0 then
+    else if Int32.compare chs.chs_rxseqno header.seqno <> 0 then
         Some (X_frame_out_of_sequence header)
     else
         None
 
-let c_rxframe_aux ?ansv vcons cs eis eip failedTx rxq txq seqno more data =
-    ei_frame eis eip failedTx more data >>= fun (ack, eisopt) ->
+let ch_rxf_aux ?ansv vcons chs ies iep failedTx rxq txq seqno more data =
+    ie_frame ies iep failedTx more data >>= fun (ack, iesopt) ->
     let rxv =
-        match eisopt with
-        | Some eis ->
-            vcons eis
+        match iesopt with
+        | Some ies ->
+            vcons ies
         | None ->
             match ansv with
             | None ->
                 S_mrx_new
-            | Some (ansno, cxp, eim) ->
-                S_mrx_ans (cxp, N32_map.delete ansno eim)
+            | Some (ansno, cxp, iem) ->
+                S_mrx_ans (cxp, N32_map.delete ansno iem)
     in
-    let cs = {
-        cs with
-        cs_rxseqno = seqno;
-        cs_rxv = rxv;
-        cs_rxq = rxq;
-        cs_txq = txq;
+    let chs = {
+        chs with
+        chs_rxseqno = seqno;
+        chs_rxv = rxv;
+        chs_rxq = rxq;
+        chs_txq = txq;
     } in
-    Cf_cmonad.return (Cf_exnopt.U (ack, cs))
+    Cf_cmonad.return (Cf_exnopt.U (ack, chs))
 
-let c_seqno_adjust cs data =
-    Int32.add cs.cs_rxseqno (Int32.of_int (Cf_message.length data))
+let ch_seqno_adjust chs data =
+    Int32.add chs.chs_rxseqno (Int32.of_int (Cf_message.length data))
 
-let c_mrx_variant_cons_msg sxp eis = S_mrx_msg (sxp, eis)
+let ch_mrx_vcons_msg sxp ies = S_mrx_msg (sxp, ies)
 
-let c_rxframe_msg cs cp header more data =
-    match c_rxframe_header cs cp header with
+let ch_rxf_msg chs chp header more data =
+    match ch_rxf_header chs chp header with
     | Some error ->
-        c_failed cs cp error
+        ch_failed chs chp error
     | None ->
-        match cs.cs_rxv with
-        | S_mrx_new when sx_msgno_check_queue header cs.cs_txq -> begin
-            sx_harness cp.cp_profile#msg header.msgno >>= fun (sxp, sxj) ->
-            cp.cp_exchangeTx#put sxj >>= fun () ->
-            let seqno = c_seqno_adjust cs data in
-            let txq = Cf_deque.A.push sxp cs.cs_txq in
-            let vcons = c_mrx_variant_cons_msg sxp in
-            c_rxframe_aux vcons cs ei_state0 sxp.sxp_req sxp.sxp_failedTx
-                cs.cs_rxq txq seqno more data
+        match chs.chs_rxv with
+        | S_mrx_new when sx_msgno_check_queue header chs.chs_txq -> begin
+            sx_harness chp.chp_profile#msg header.msgno >>= fun (sxp, sxf) ->
+            chp.chp_exchangeTx#put sxf >>= fun () ->
+            let seqno = ch_seqno_adjust chs data in
+            let txq = Cf_deque.A.push sxp chs.chs_txq in
+            let vcons = ch_mrx_vcons_msg sxp in
+            ch_rxf_aux vcons chs ies0 sxp.sxp_req sxp.sxp_failedTx
+                chs.chs_rxq txq seqno more data
           end
-        | S_mrx_msg (sxp, eis) when sx_msgno_check header sxp -> begin
-            let seqno = c_seqno_adjust cs data in
-            let vcons = c_mrx_variant_cons_msg sxp in
-            c_rxframe_aux vcons cs eis sxp.sxp_req sxp.sxp_failedTx cs.cs_rxq
-                cs.cs_txq seqno more data
+        | S_mrx_msg (sxp, ies) when sx_msgno_check header sxp -> begin
+            let seqno = ch_seqno_adjust chs data in
+            let vcons = ch_mrx_vcons_msg sxp in
+            ch_rxf_aux vcons chs ies sxp.sxp_req sxp.sxp_failedTx chs.chs_rxq
+                chs.chs_txq seqno more data
           end
         | _ ->
-            c_failed cs cp (X_message_in_progress header)
+            ch_failed chs chp (X_message_in_progress header)
 
 type crxrsp1 =
     | F_rsp1_rpy of
-        (cxplug -> eiplug -> eistate -> mrxvariant) *
-        (cprofile_basic -> eprofile) *
-        (eijack -> cxrsp)
+        (cxpad -> iepad -> iestate -> chsrxvariant) *
+        (chprofile_basic -> eprofile) *
+        (iefix -> cxrsp)
     | F_rsp1_err of
-        (cxplug -> eiplug -> eistate -> mrxvariant) *
-        (cprofile_basic -> eprofile) *
-        (eijack -> cxrsp)
+        (cxpad -> iepad -> iestate -> chsrxvariant) *
+        (chprofile_basic -> eprofile) *
+        (iefix -> cxrsp)
 
 let crxrsp1_rpy =
-    let variant cxp eip eis = S_mrx_rpy (cxp, eip, eis) in
+    let variant cxp iep ies = S_mrx_rpy (cxp, iep, ies) in
     let profile p = p#rpy in
-    let message eij = M_clt_err eij in
+    let message ief = M_clt_err ief in
     F_rsp1_rpy (variant, profile, message)
 
 let crxrsp1_err =
-    let variant cxp eip eis = S_mrx_err (cxp, eip, eis) in
+    let variant cxp iep ies = S_mrx_err (cxp, iep, ies) in
     let profile p = p#err in
-    let message eij = M_clt_err eij in
+    let message ief = M_clt_err ief in
     F_rsp1_err (variant, profile, message)
 
-let c_rxframe_rsp1 rspv cs cp header more data =
-    match c_rxframe_header cs cp header with
+let ch_rxf_rsp1 rspv chs chp header more data =
+    match ch_rxf_header chs chp header with
     | Some error ->
-        c_failed cs cp error
+        ch_failed chs chp error
     | None ->
-        match rspv, cs.cs_rxv with
-        | F_rsp1_rpy (vcons, _, _), S_mrx_rpy (cxp, eip, eis)
-        | F_rsp1_err (vcons, _, _), S_mrx_err (cxp, eip, eis)
+        match rspv, chs.chs_rxv with
+        | F_rsp1_rpy (vcons, _, _), S_mrx_rpy (cxp, iep, ies)
+        | F_rsp1_err (vcons, _, _), S_mrx_err (cxp, iep, ies)
           when cx_msgno_check header cxp -> begin
-            let seqno = c_seqno_adjust cs data in
-            let vcons = vcons cxp eip in
-            c_rxframe_aux vcons cs eis eip cxp.cxp_failedTx cs.cs_rxq
-                cs.cs_txq seqno more data
+            let seqno = ch_seqno_adjust chs data in
+            let vcons = vcons cxp iep in
+            ch_rxf_aux vcons chs ies iep cxp.cxp_failedTx chs.chs_rxq
+                chs.chs_txq seqno more data
           end
         | F_rsp1_rpy (vcons, eprf, mcons), S_mrx_new
         | F_rsp1_err (vcons, eprf, mcons), S_mrx_new -> begin
-            match Cf_deque.B.pop cs.cs_rxq with
+            match Cf_deque.B.pop chs.chs_rxq with
             | Some (cxp, rxq) when cx_msgno_check header cxp ->
-                let eprf = eprf cp.cp_profile in
-                ei_harness eprf#limits >>= fun (eip, eij) ->
-                cxp.cxp_rspTx#put (mcons eij) >>= fun () ->
-                let seqno = c_seqno_adjust cs data in
-                let vcons = vcons cxp eip in
-                c_rxframe_aux vcons cs ei_state0 eip cxp.cxp_failedTx rxq
-                    cs.cs_txq seqno more data
+                let eprf = eprf chp.chp_profile in
+                ie_harness eprf#limits >>= fun (iep, ief) ->
+                cxp.cxp_rspTx#put (mcons ief) >>= fun () ->
+                let seqno = ch_seqno_adjust chs data in
+                let vcons = vcons cxp iep in
+                ch_rxf_aux vcons chs ies0 iep cxp.cxp_failedTx rxq chs.chs_txq
+                    seqno more data
             | _ ->
-                c_failed cs cp (X_response_unexpected header)
+                ch_failed chs chp (X_response_unexpected header)
           end
         | _ ->
-            c_failed cs cp (X_message_in_progress header)
+            ch_failed chs chp (X_message_in_progress header)
 
-let c_mrx_variant_cons_ans cxp ansno eim eip eis =
-    S_mrx_ans (cxp, N32_map.replace (ansno, (eip, eis)) eim)
+let ch_mrx_vcons_ans cxp ansno iem iep ies =
+    S_mrx_ans (cxp, N32_map.replace (ansno, (iep, ies)) iem)
 
-let c_rxframe_ans cs cp ansno header more data =
-    match c_rxframe_header cs cp header with
+let ch_rxf_ans chs chp ansno header more data =
+    match ch_rxf_header chs chp header with
     | Some error ->
-        c_failed cs cp error
+        ch_failed chs chp error
     | None ->
-        match cs.cs_rxv with
+        match chs.chs_rxv with
         | S_mrx_new -> begin
-            match Cf_deque.B.pop cs.cs_rxq with
+            match Cf_deque.B.pop chs.chs_rxq with
             | Some (cxp, rxq) when cx_msgno_check header cxp ->
-                ei_harness cp.cp_profile#ans#limits >>= fun (eip, eij) ->
-                cxp.cxp_rspTx#put (M_clt_ans (ansno, eij)) >>= fun () ->
-                let seqno = c_seqno_adjust cs data in
+                ie_harness chp.chp_profile#ans#limits >>= fun (iep, ief) ->
+                cxp.cxp_rspTx#put (M_clt_ans (ansno, ief)) >>= fun () ->
+                let seqno = ch_seqno_adjust chs data in
                 let ansv = ansno, cxp, N32_map.nil in
-                let vcons = c_mrx_variant_cons_ans cxp ansno N32_map.nil eip in
-                c_rxframe_aux ~ansv vcons cs ei_state0 eip cxp.cxp_failedTx rxq
-                    cs.cs_txq seqno more data
+                let vcons = ch_mrx_vcons_ans cxp ansno N32_map.nil iep in
+                ch_rxf_aux ~ansv vcons chs ies0 iep cxp.cxp_failedTx rxq
+                    chs.chs_txq seqno more data
             | _ ->
-                c_failed cs cp (X_response_unexpected header)
+                ch_failed chs chp (X_response_unexpected header)
           end
-        | S_mrx_ans (cxp, eim) when cx_msgno_check header cxp -> begin
-            let seqno = c_seqno_adjust cs data in
+        | S_mrx_ans (cxp, iem) when cx_msgno_check header cxp -> begin
+            let seqno = ch_seqno_adjust chs data in
             match
-                try Cf_exnopt.U (N32_map.search ansno eim)
+                try Cf_exnopt.U (N32_map.search ansno iem)
                 with x -> Cf_exnopt.X x
             with
-            | Cf_exnopt.U (eip, eis) ->
-                let ansv = ansno, cxp, eim in
-                let vcons = c_mrx_variant_cons_ans cxp ansno eim eip in
-                c_rxframe_aux ~ansv vcons cs eis eip cxp.cxp_failedTx cs.cs_rxq
-                    cs.cs_txq seqno more data
+            | Cf_exnopt.U (iep, ies) ->
+                let ansv = ansno, cxp, iem in
+                let vcons = ch_mrx_vcons_ans cxp ansno iem iep in
+                ch_rxf_aux ~ansv vcons chs ies iep cxp.cxp_failedTx chs.chs_rxq
+                    chs.chs_txq seqno more data
             | Cf_exnopt.X Not_found ->
-                ei_harness cp.cp_profile#ans#limits >>= fun (eip, eij) ->
-                cxp.cxp_rspTx#put (M_clt_ans (ansno, eij)) >>= fun () ->
-                let ansv = ansno, cxp, eim in
-                let vcons = c_mrx_variant_cons_ans cxp ansno eim eip in
-                c_rxframe_aux ~ansv vcons cs ei_state0 eip cxp.cxp_failedTx
-                    cs.cs_rxq cs.cs_txq seqno more data
+                ie_harness chp.chp_profile#ans#limits >>= fun (iep, ief) ->
+                cxp.cxp_rspTx#put (M_clt_ans (ansno, ief)) >>= fun () ->
+                let ansv = ansno, cxp, iem in
+                let vcons = ch_mrx_vcons_ans cxp ansno iem iep in
+                ch_rxf_aux ~ansv vcons chs ies0 iep cxp.cxp_failedTx
+                    chs.chs_rxq chs.chs_txq seqno more data
             | Cf_exnopt.X _ as v ->
                 assert (not true);
                 Cf_cmonad.return v
           end
         | _ ->
-            c_failed cs cp (X_message_in_progress header)
+            ch_failed chs chp (X_message_in_progress header)
 
-let c_rxframe_nul_aux cs cp cxp rxq eim header =
-    if N32_map.empty eim then begin
+let ch_rxf_nul_aux chs chp cxp rxq iem header =
+    if N32_map.empty iem then begin
         cxp.cxp_rspTx#put M_clt_nul >>= fun () ->
-        Cf_cmonad.return (Cf_exnopt.U (0, { cs with cs_rxq = rxq }))
+        Cf_cmonad.return (Cf_exnopt.U (0, { chs with chs_rxq = rxq }))
     end
     else
-        c_failed cs cp (X_message_in_progress header)
+        ch_failed chs chp (X_message_in_progress header)
 
-let c_rxframe_nul cs cp header =
-    match c_rxframe_header cs cp header with
+let ch_rxf_nul chs chp header =
+    match ch_rxf_header chs chp header with
     | Some error ->
-        c_failed cs cp error
+        ch_failed chs chp error
     | None ->
-        match cs.cs_rxv with
+        match chs.chs_rxv with
         | S_mrx_new -> begin
-            match Cf_deque.B.pop cs.cs_rxq with
+            match Cf_deque.B.pop chs.chs_rxq with
             | Some (cxp, rxq) when cx_msgno_check header cxp ->
-                c_rxframe_nul_aux cs cp cxp rxq N32_map.nil header
+                ch_rxf_nul_aux chs chp cxp rxq N32_map.nil header
             | _ ->
-                c_failed cs cp (X_response_unexpected header)
+                ch_failed chs chp (X_response_unexpected header)
           end
-        | S_mrx_ans (cxp, eim) when cx_msgno_check header cxp ->
-            c_rxframe_nul_aux cs cp cxp cs.cs_rxq eim header
+        | S_mrx_ans (cxp, iem) when cx_msgno_check header cxp ->
+            ch_rxf_nul_aux chs chp cxp chs.chs_rxq iem header
         | _ ->
-            c_failed cs cp (X_message_in_progress header)
+            ch_failed chs chp (X_message_in_progress header)
 
-let c_rxframe cs cp = function
+let ch_rxf chs chp = function
     | `MSG (header, more, data) ->
-        c_rxframe_msg cs cp header more data
+        ch_rxf_msg chs chp header more data
     | `RPY (header, more, data) ->
-        c_rxframe_rsp1 crxrsp1_rpy cs cp header more data
+        ch_rxf_rsp1 crxrsp1_rpy chs chp header more data
     | `ERR (header, more, data) ->
-        c_rxframe_rsp1 crxrsp1_err cs cp header more data
+        ch_rxf_rsp1 crxrsp1_err chs chp header more data
     | `ANS (ansno, header, more, data) ->
-        c_rxframe_ans cs cp ansno header more data
-    | (`NUL header : [< frame ]) ->
-        c_rxframe_nul cs cp header
+        ch_rxf_ans chs chp ansno header more data
+    | `NUL header ->
+        ch_rxf_nul chs chp header
 
-let c_rxflow_msg_guard cs eis sxp cont =
-    ei_flow_guard eis sxp.sxp_req begin fun (ack, eisopt) ->
+let ch_rxf_msg_guard chs ies sxp cont =
+    ie_flow_guard ies sxp.sxp_req begin fun (ack, iesopt) ->
         let rxv =
-            match eisopt with
+            match iesopt with
             | None ->
                 S_mrx_new
-            | Some eis ->
-                assert (eis.eis_more == Iom_stream.More);
-                S_mrx_msg (sxp, eis)
+            | Some ies ->
+                assert (ies.ies_more == Iom_stream.More);
+                S_mrx_msg (sxp, ies)
         in
-        cont (ack, { cs with cs_rxv = rxv })
+        cont (ack, { chs with chs_rxv = rxv })
     end
 
-let c_rxflow_rsp1_guard frsp cs eis cxp eip cont =
-    ei_flow_guard eis eip begin fun (ack, eisopt) ->
+let ch_rxf_rsp1_guard frsp chs ies cxp iep cont =
+    ie_flow_guard ies iep begin fun (ack, iesopt) ->
         let rxv =
-            match eisopt with
+            match iesopt with
             | None ->
                 S_mrx_new
-            | Some eis ->
-                assert (eis.eis_more == Iom_stream.More);
+            | Some ies ->
+                assert (ies.ies_more == Iom_stream.More);
                 let vcons =
                     match frsp with
                     | F_rsp1_rpy (vcons, _, _)
                     | F_rsp1_err (vcons, _, _) ->
                         vcons
                 in
-                vcons cxp eip eis
+                vcons cxp iep ies
         in
-        cont (ack, { cs with cs_rxv = rxv })
+        cont (ack, { chs with chs_rxv = rxv })
     end
 
-let c_rxflow_ans1_guard cs cxp eim cont (ansno, (eip, eis)) =
-    ei_flow_guard eis eip begin fun (ack, eisopt) ->
-        let eim =
-            match eisopt with
+let ch_rxf_ans1_guard chs cxp iem cont (ansno, (iep, ies)) =
+    ie_flow_guard ies iep begin fun (ack, iesopt) ->
+        let iem =
+            match iesopt with
             | None ->
-                N32_map.delete ansno eim
-            | Some eis ->
-                assert (eis.eis_more == Iom_stream.More);
-                N32_map.replace (ansno, (eip, eis)) eim
+                N32_map.delete ansno iem
+            | Some ies ->
+                assert (ies.ies_more == Iom_stream.More);
+                N32_map.replace (ansno, (iep, ies)) iem
         in
-        cont (ack, { cs with cs_rxv = S_mrx_ans (cxp, eim) })
+        cont (ack, { chs with chs_rxv = S_mrx_ans (cxp, iem) })
     end
 
-let c_rxflow_ans_guard cs cxp eim cont =
-    let z = N32_map.to_seq_incr eim in
-    let z = Cf_seq.map (c_rxflow_ans1_guard cs cxp eim cont) z in
+let ch_rxf_ans_guard chs cxp iem cont =
+    let z = N32_map.to_seq_incr iem in
+    let z = Cf_seq.map (ch_rxf_ans1_guard chs cxp iem cont) z in
     Cf_seq.C.sequence z
 
-let c_rxflow_guard cs cont =
-    match cs.cs_rxv with
+let ch_rxf_guard chs cont =
+    match chs.chs_rxv with
     | S_mrx_new ->
         Cf_cmonad.nil
-    | S_mrx_msg (sxp, eis) ->
-        c_rxflow_msg_guard cs eis sxp cont
-    | S_mrx_rpy (cxp, eip, eis) ->
-        c_rxflow_rsp1_guard crxrsp1_rpy cs eis cxp eip cont
-    | S_mrx_err (cxp, eip, eis) ->
-        c_rxflow_rsp1_guard crxrsp1_err cs eis cxp eip cont
-    | S_mrx_ans (cxp, eim) ->
-        c_rxflow_ans_guard cs cxp eim cont
+    | S_mrx_msg (sxp, ies) ->
+        ch_rxf_msg_guard chs ies sxp cont
+    | S_mrx_rpy (cxp, iep, ies) ->
+        ch_rxf_rsp1_guard crxrsp1_rpy chs ies cxp iep cont
+    | S_mrx_err (cxp, iep, ies) ->
+        ch_rxf_rsp1_guard crxrsp1_err chs ies cxp iep cont
+    | S_mrx_ans (cxp, iem) ->
+        ch_rxf_ans_guard chs cxp iem cont
 
-let c_txframe_sxrsp_guard cs cp cont =
-    match Cf_deque.B.pop cs.cs_txq with
+let ch_txf_sxrsp_guard chs chp cont =
+    match Cf_deque.B.pop chs.chs_txq with
     | None ->
         Cf_cmonad.nil
     | Some (sxp, txq) ->
         sxp.sxp_rspRx#get begin function
-        | M_srv_rpy eop ->
-            let txv = S_mtx_rpy (sxp, eop, eo_state0) in
-            cont (0, [], { cs with cs_txv = txv; cs_txq = txq })
-        | M_srv_err eop ->
-            let txv = S_mtx_err (sxp, eop, eo_state0) in
-            cont (0, [], { cs with cs_txv = txv; cs_txq = txq })
-        | M_srv_ans (ansno, eop) ->
-            let eom = N32_map.replace (ansno, (eop, eo_state0)) N32_map.nil in
-            let eoq = Cf_deque.A.push (ansno, eop) Cf_deque.nil in
-            let txv = S_mtx_ans (sxp, eom, eoq, Iom_stream.More) in
-            cont (0, [], { cs with cs_txv = txv; cs_txq = txq })
+        | M_srv_rpy oep ->
+            let txv = S_mtx_rpy (sxp, oep, oes0) in
+            cont (0, [], { chs with chs_txv = txv; chs_txq = txq })
+        | M_srv_err oep ->
+            let txv = S_mtx_err (sxp, oep, oes0) in
+            cont (0, [], { chs with chs_txv = txv; chs_txq = txq })
+        | M_srv_ans (ansno, oep) ->
+            let oem = N32_map.replace (ansno, (oep, oes0)) N32_map.nil in
+            let oeq = Cf_deque.A.push (ansno, oep) Cf_deque.nil in
+            let txv = S_mtx_ans (sxp, oem, oeq, Iom_stream.More) in
+            cont (0, [], { chs with chs_txv = txv; chs_txq = txq })
         | M_srv_nul ->
             let header = {
-                channo = cp.cp_channo;
+                channo = chp.chp_channo;
                 msgno = sxp.sxp_msgno;
-                seqno = cs.cs_txseqno;
+                seqno = chs.chs_txseqno;
             } in
-            cont (0, [ `NUL header ], { cs with cs_txq = txq })
+            cont (0, [ `NUL header ], { chs with chs_txq = txq })
         end
 
-let c_txframe_cxmsg_guard cs cp cont =
-    cp.cp_exchangeRx#get begin fun cxp ->
-        let txv = S_mtx_msg (cxp, eo_state0) in
+let ch_txf_cxmsg_guard chs chp cont =
+    chp.chp_exchangeRx#get begin fun cxp ->
+        let txv = S_mtx_msg (cxp, oes0) in
         if
             Cf_deque.predicate begin fun p ->
                 Int32.compare p.cxp_msgno cxp.cxp_msgno <> 0
-            end cs.cs_rxq
+            end chs.chs_rxq
         then begin
-            let rxq = Cf_deque.A.push cxp cs.cs_rxq in
-            cont (0, [], { cs with cs_rxq = rxq; cs_txv = txv })
+            let rxq = Cf_deque.A.push cxp chs.chs_rxq in
+            cont (0, [], { chs with chs_rxq = rxq; chs_txv = txv })
         end
         else begin
             errj#error "Beep_core: client exchange msgno still in progress!";
-            cont (0, [], cs)
+            cont (0, [], chs)
         end
     end
 
-let c_txframe_eo_aux cs cp msgno vcons fcons cont (eosopt, lmpopt) =
+let ch_txf_oe_aux chs chp msgno vcons fcons cont (oesopt, lmpopt) =
     let txv =
-        match eosopt with
+        match oesopt with
         | None -> S_mtx_new
-        | Some eos -> vcons eos
+        | Some oes -> vcons oes
     in
-    let eat, fs, cs =
+    let eat, fs, chs =
         match lmpopt with
         | Some (length, more, payload) ->
             let header = {
-                channo = cp.cp_channo;
+                channo = chp.chp_channo;
                 msgno = msgno;
-                seqno = cs.cs_txseqno;
+                seqno = chs.chs_txseqno;
             } in
-            let seqno = Int32.add cs.cs_txseqno (Int32.of_int length) in
+            let seqno = Int32.add chs.chs_txseqno (Int32.of_int length) in
             let frame = fcons header more payload in
-            length, [ frame ], { cs with cs_txseqno = seqno; cs_txv = txv }
+            length, [ frame ], { chs with chs_txseqno = seqno; chs_txv = txv }
         | None ->
-            0, [], { cs with cs_txv = txv }
+            0, [], { chs with chs_txv = txv }
     in
-    cont (eat, fs, cs)
+    cont (eat, fs, chs)
 
-let c_txframe_eo_guard window cs cp msgno vcons fcons eop eos cont =
-    let aux = c_txframe_eo_aux cs cp msgno vcons fcons cont in
-    eo_event_guard window eos eop aux
+let ch_txf_oe_guard window chs chp msgno vcons fcons oep oes cont =
+    let aux = ch_txf_oe_aux chs chp msgno vcons fcons cont in
+    oe_event_guard window oes oep aux
 
-let c_txframe_fcons_msg header more payload = `MSG (header, more, payload)
-let c_txframe_fcons_rpy header more payload = `RPY (header, more, payload)
-let c_txframe_fcons_err header more payload = `ERR (header, more, payload)
+let ch_txf_fcons_msg header more payload = `MSG (header, more, payload)
+let ch_txf_fcons_rpy header more payload = `RPY (header, more, payload)
+let ch_txf_fcons_err header more payload = `ERR (header, more, payload)
 
-let rec c_txframe_ans_guard window cs cp sxp eom eoq rmore cont (ansno, eop) =
+let rec ch_txf_ans_guard window chs chp sxp oem oeq rmore cont (ansno, oep) =
     match
         try
-            let (_, eos), eomx = N32_map.extract ansno eom in
-            Cf_exnopt.U (eos, eomx)
+            let (_, oes), oemx = N32_map.extract ansno oem in
+            Cf_exnopt.U (oes, oemx)
         with
         | x ->
             assert (x = Not_found);
     with
     | Cf_exnopt.X _  ->
         Cf_cmonad.nil
-    | Cf_exnopt.U (eos, eomx) ->
-        eo_event_guard window eos eop begin fun (eosopt, lmpopt) ->
+    | Cf_exnopt.U (oes, oemx) ->
+        oe_event_guard window oes oep begin fun (oesopt, lmpopt) ->
             let txv =
-                match eosopt with
-                | None when N32_map.empty eomx && rmore = Iom_stream.Last ->
+                match oesopt with
+                | None when N32_map.empty oemx && rmore = Iom_stream.Last ->
                     S_mtx_new
                 | None ->
-                    let s = N32_map.to_list_incr eomx in
+                    let s = N32_map.to_list_incr oemx in
                     let s =
-                        List.rev_map (fun (ansno, (eop, _)) -> ansno, eop) s
+                        List.rev_map (fun (ansno, (oep, _)) -> ansno, oep) s
                     in
-                    let eoq = Cf_deque.A.of_list s in
-                    S_mtx_ans (sxp, eomx, eoq, rmore)
-                | Some eos ->
-                    assert (eos.eos_more = Iom_stream.More);
-                    let eom = N32_map.replace (ansno, (eop, eos)) eomx in
-                    S_mtx_ans (sxp, eom, eoq, rmore)
+                    let oeq = Cf_deque.A.of_list s in
+                    S_mtx_ans (sxp, oemx, oeq, rmore)
+                | Some oes ->
+                    assert (oes.oes_more = Iom_stream.More);
+                    let oem = N32_map.replace (ansno, (oep, oes)) oemx in
+                    S_mtx_ans (sxp, oem, oeq, rmore)
             in
-            let eat, fs, cs =
+            let eat, fs, chs =
                 match lmpopt with
                 | Some (length, more, payload) ->
                     let header = {
-                        channo = cp.cp_channo;
+                        channo = chp.chp_channo;
                         msgno = sxp.sxp_msgno;
-                        seqno = cs.cs_txseqno;
+                        seqno = chs.chs_txseqno;
                     } in
                     let seqno =
-                        Int32.add cs.cs_txseqno (Int32.of_int length)
+                        Int32.add chs.chs_txseqno (Int32.of_int length)
                     in
                     let ans = `ANS (ansno, header, more, payload) in
-                    let cs = { cs with cs_txseqno = seqno; cs_txv = txv } in
+                    let chs = {
+                        chs with
+                        chs_txseqno = seqno;
+                        chs_txv = txv;
+                    } in
                     let fs =
                         match txv with
                         | S_mtx_new ->
                         | _ ->
                             [ ans ]
                     in
-                    length, fs, cs
+                    length, fs, chs
                 | None ->
                     let header = {
-                        channo = cp.cp_channo;
+                        channo = chp.chp_channo;
                         msgno = sxp.sxp_msgno;
-                        seqno = cs.cs_txseqno;
+                        seqno = chs.chs_txseqno;
                     } in
-                    0, [ `NUL header ], { cs with cs_txv = txv }
+                    0, [ `NUL header ], { chs with chs_txv = txv }
             in
-            cont (eat, fs, cs)
+            cont (eat, fs, chs)
         end
 
-let c_txframe_nul_guard cs cp sxp eom eoq cont =
+let ch_txf_nul_guard chs chp sxp oem oeq cont =
     sxp.sxp_rspRx#get begin function
-    | M_srv_ans (ansno, eop) ->
-        if N32_map.member ansno eom then begin
+    | M_srv_ans (ansno, oep) ->
+        if N32_map.member ansno oem then begin
             errj#error "Beep_core: service response ansno still in progress!";
-            cont (0, [], cs)
+            cont (0, [], chs)
         end
         else begin
-            let eom = N32_map.replace (ansno, (eop, eo_state0)) N32_map.nil in
-            let eoq = Cf_deque.A.push (ansno, eop) Cf_deque.nil in
-            let txv = S_mtx_ans (sxp, eom, eoq, Iom_stream.More) in
-            cont (0, [], { cs with cs_txv = txv })
+            let oem = N32_map.replace (ansno, (oep, oes0)) N32_map.nil in
+            let oeq = Cf_deque.A.push (ansno, oep) Cf_deque.nil in
+            let txv = S_mtx_ans (sxp, oem, oeq, Iom_stream.More) in
+            cont (0, [], { chs with chs_txv = txv })
         end
     | M_srv_nul ->
-        if N32_map.empty eom then begin
+        if N32_map.empty oem then begin
             let header = {
-                channo = cp.cp_channo;
+                channo = chp.chp_channo;
                 msgno = sxp.sxp_msgno;
-                seqno = cs.cs_txseqno;
+                seqno = chs.chs_txseqno;
             } in
-            cont (0, [ `NUL header ], { cs with cs_txv = S_mtx_new })
+            cont (0, [ `NUL header ], { chs with chs_txv = S_mtx_new })
         end
         else begin
-            let txv = S_mtx_ans (sxp, eom, eoq, Iom_stream.Last) in
-            cont (0, [], { cs with cs_txv = txv })
+            let txv = S_mtx_ans (sxp, oem, oeq, Iom_stream.Last) in
+            cont (0, [], { chs with chs_txv = txv })
         end
     | _ ->
         errj#error "Beep_core: service response type invalid!";
-        cont (0, [], cs)
+        cont (0, [], chs)
     end
 
-let c_txframe_guard window cs cp cont =
-    match cs.cs_txv with
+let ch_txf_guard window chs chp cont =
+    if window < 0 then
+        invalid_arg "Beep_core.ch_txf_guard: window < 0";
+    match chs.chs_txv with
     | S_mtx_new ->
-        c_txframe_sxrsp_guard cs cp cont >>= fun () ->
-        c_txframe_cxmsg_guard cs cp cont
+        ch_txf_sxrsp_guard chs chp cont >>= fun () ->
+        ch_txf_cxmsg_guard chs chp cont
     | S_mtx_msg _
     | S_mtx_rpy _
     | S_mtx_err _
       when window <= 0 ->
         Cf_cmonad.nil
-    | S_mtx_msg (cxp, eos) ->
-        let vcons eos = S_mtx_msg (cxp, eos) in
-        c_txframe_eo_guard window cs cp cxp.cxp_msgno vcons c_txframe_fcons_msg
-            cxp.cxp_req eos cont
-    | S_mtx_rpy (sxp, eop, eos) ->
-        let vcons eos = S_mtx_rpy (sxp, eop, eos) in
-        c_txframe_eo_guard window cs cp sxp.sxp_msgno vcons c_txframe_fcons_rpy
-            eop eos cont
-    | S_mtx_err (sxp, eop, eos) ->
-        let vcons eos = S_mtx_err (sxp, eop, eos) in
-        c_txframe_eo_guard window cs cp sxp.sxp_msgno vcons c_txframe_fcons_err
-            eop eos cont
-    | S_mtx_ans (sxp, eom, eoq, rmore) ->
-        let z = Cf_deque.B.to_seq eoq in
-        let eoq =
-            match Cf_deque.B.pop eoq with
+    | S_mtx_msg (cxp, oes) ->
+        let vcons oes = S_mtx_msg (cxp, oes) in
+        ch_txf_oe_guard window chs chp cxp.cxp_msgno vcons
+            ch_txf_fcons_msg cxp.cxp_req oes cont
+    | S_mtx_rpy (sxp, oep, oes) ->
+        let vcons oes = S_mtx_rpy (sxp, oep, oes) in
+        ch_txf_oe_guard window chs chp sxp.sxp_msgno vcons
+            ch_txf_fcons_rpy oep oes cont
+    | S_mtx_err (sxp, oep, oes) ->
+        let vcons oes = S_mtx_err (sxp, oep, oes) in
+        ch_txf_oe_guard window chs chp sxp.sxp_msgno vcons
+            ch_txf_fcons_err oep oes cont
+    | S_mtx_ans (sxp, oem, oeq, rmore) ->
+        let z = Cf_deque.B.to_seq oeq in
+        let oeq =
+            match Cf_deque.B.pop oeq with
             | None -> Cf_deque.nil
             | Some (hd, tl) -> Cf_deque.A.push hd tl
         in
-        let z =
-            Cf_seq.map begin
-                c_txframe_ans_guard window cs cp sxp eom eoq rmore cont
-            end z
-        in
+        let f = ch_txf_ans_guard window chs chp sxp oem oeq rmore cont in
+        let z = Cf_seq.map f z in
         Cf_seq.C.sequence z >>= fun () ->
         match rmore with
-        | Iom_stream.More -> c_txframe_nul_guard cs cp sxp eom eoq cont
+        | Iom_stream.More -> ch_txf_nul_guard chs chp sxp oem oeq cont
         | Iom_stream.Last -> Cf_cmonad.nil
 
-let c_txready_single window cs cp msgno vcons fcons eos eop =
-    let aux = c_txframe_eo_aux cs cp msgno vcons fcons Cf_cmonad.return in
-    eo_ready window eos eop >>= aux
+let ch_txr_single window chs chp msgno vcons fcons oes oep =
+    let aux = ch_txf_oe_aux chs chp msgno vcons fcons Cf_cmonad.return in
+    oe_ready window oes oep >>= aux
 
-let rec c_txready_answer_aux frs eoq' seqno window cs cp sxp eom eoq rmore =
-    match Cf_deque.B.pop eoq with
+let rec ch_txr_answer_aux frs oeq' seqno window chs chp sxp oem oeq rmore =
+    match Cf_deque.B.pop oeq with
     | None ->
-        let eat = Int32.to_int (Int32.sub seqno cs.cs_txseqno) in
+        let eat = Int32.to_int (Int32.sub seqno chs.chs_txseqno) in
         let frs, txv =
-            if rmore = Iom_stream.Last && N32_map.empty eom then begin
+            if rmore = Iom_stream.Last && N32_map.empty oem then begin
                 let header = {
-                    channo = cp.cp_channo;
+                    channo = chp.chp_channo;
                     seqno = seqno;
                     msgno = sxp.sxp_msgno;
                 } in
                 frs, S_mtx_new
             end
             else
-                frs, S_mtx_ans (sxp, eom, eoq', rmore)
+                frs, S_mtx_ans (sxp, oem, oeq', rmore)
         in
-        let cs = { cs with cs_txv = txv; cs_txseqno = seqno } in
-        Cf_cmonad.return (eat, List.rev frs, cs)
+        let chs = { chs with chs_txv = txv; chs_txseqno = seqno } in
+        Cf_cmonad.return (eat, List.rev frs, chs)
     | Some _ when window <= 0 ->
-        let eat = Int32.to_int (Int32.sub seqno cs.cs_txseqno) in
-        let txv = S_mtx_ans (sxp, eom, Cf_deque.catenate eoq eoq', rmore) in
-        let cs = { cs with cs_txv = txv; cs_txseqno = seqno } in
-        Cf_cmonad.return (eat, List.rev frs, cs)
-    | Some ((ansno, _ as qentry), eoq) ->
+        let eat = Int32.to_int (Int32.sub seqno chs.chs_txseqno) in
+        let txv = S_mtx_ans (sxp, oem, Cf_deque.catenate oeq oeq', rmore) in
+        let chs = { chs with chs_txv = txv; chs_txseqno = seqno } in
+        Cf_cmonad.return (eat, List.rev frs, chs)
+    | Some ((ansno, _ as qentry), oeq) ->
         match
-            try Cf_exnopt.U (N32_map.extract ansno eom)
+            try Cf_exnopt.U (N32_map.extract ansno oem)
             with x -> assert(x = Not_found); Cf_exnopt.X x
         with
         | Cf_exnopt.X _ ->
-            c_txready_answer_aux frs eoq' seqno window cs cp sxp eom eoq rmore
-        | Cf_exnopt.U ((eop, eos), eom) ->
-            eo_ready window eos eop >>= fun (eosopt, lmpopt) ->
-            let eom, eoq' =
-                match eosopt with
+            ch_txr_answer_aux frs oeq' seqno window chs chp sxp oem oeq rmore
+        | Cf_exnopt.U ((oep, oes), oem) ->
+            oe_ready window oes oep >>= fun (oesopt, lmpopt) ->
+            let oem, oeq' =
+                match oesopt with
                 | None ->
-                    eom, eoq'
-                | Some eos ->
-                    let eom = N32_map.replace (ansno, (eop, eos)) eom in
-                    let eoq' = Cf_deque.A.push qentry eoq' in
-                    eom, eoq'
+                    oem, oeq'
+                | Some oes ->
+                    let oem = N32_map.replace (ansno, (oep, oes)) oem in
+                    let oeq' = Cf_deque.A.push qentry oeq' in
+                    oem, oeq'
             in
             let frs, seqno =
                 match lmpopt with
                     frs, seqno
                 | Some (length, more, payload) ->
                     let header = {
-                        channo = cp.cp_channo;
+                        channo = chp.chp_channo;
                         seqno = seqno;
                         msgno = sxp.sxp_msgno;
                     } in
                     let frs = `ANS (ansno, header, more, payload) :: frs in
                     frs, seqno
             in
-            c_txready_answer_aux frs eoq' seqno window cs cp sxp eom eoq rmore
+            ch_txr_answer_aux frs oeq' seqno window chs chp sxp oem oeq rmore
 
-let c_txready window cs cp =
-    match cs.cs_txv with
+let ch_txr window chs chp =
+    if window < 0 then
+        invalid_arg "Beep_core.ch_txr: window < 0";
+    match chs.chs_txv with
     | S_mtx_new ->
-        Cf_cmonad.return (0, [], cs)
-    | S_mtx_msg (cxp, eos) ->
-        let vcons eos = S_mtx_msg (cxp, eos) in
-        c_txready_single window cs cp cxp.cxp_msgno vcons c_txframe_fcons_msg
-            eos cxp.cxp_req
-    | S_mtx_rpy (sxp, eop, eos) ->
-        let vcons eos = S_mtx_rpy (sxp, eop, eos) in
-        c_txready_single window cs cp sxp.sxp_msgno vcons c_txframe_fcons_rpy
-            eos eop
-    | S_mtx_err (sxp, eop, eos) ->
-        let vcons eos = S_mtx_err (sxp, eop, eos) in
-        c_txready_single window cs cp sxp.sxp_msgno vcons c_txframe_fcons_err
-            eos eop
-    | S_mtx_ans (sxp, eom, eoq, rmore) ->
-        c_txready_answer_aux [] Cf_deque.nil cs.cs_txseqno window cs cp sxp eom
-            eoq rmore
+        Cf_cmonad.return (0, [], chs)
+    | S_mtx_msg (cxp, oes) ->
+        let vcons oes = S_mtx_msg (cxp, oes) in
+        ch_txr_single window chs chp cxp.cxp_msgno vcons ch_txf_fcons_msg oes
+            cxp.cxp_req
+    | S_mtx_rpy (sxp, oep, oes) ->
+        let vcons oes = S_mtx_rpy (sxp, oep, oes) in
+        ch_txr_single window chs chp sxp.sxp_msgno vcons ch_txf_fcons_rpy oes
+            oep
+    | S_mtx_err (sxp, oep, oes) ->
+        let vcons oes = S_mtx_err (sxp, oep, oes) in
+        ch_txr_single window chs chp sxp.sxp_msgno vcons ch_txf_fcons_err oes
+            oep
+    | S_mtx_ans (sxp, oem, oeq, rmore) ->
+        ch_txr_answer_aux [] Cf_deque.nil chs.chs_txseqno window chs chp sxp
+            oem oeq rmore
+
+(*--- session management ---*)
+type scontrol = Iom_stream.stop
+type snotify = Iom_stream.failed
+
+type sfix = {
+    sp_controlTx: scontrol Iom_gadget.tx;
+    sp_notifyRx: snotify Iom_gadget.rx;
+}
+
+type spad = {
+    sp_controlRx: scontrol Iom_gadget.rx;
+    sp_notifyTx: snotify Iom_gadget.tx;
+}
+
+type sstate = S_ss_unimplemented
+
+let ss0 = S_ss_unimplemented
 
 (*--- End of File [ beep_core.ml ] ---*)

beep/beep_core.mli

 
 type frame = [ msg_frame | response_frame ]
 
-val parse_frame: ?limit:Int32.t -> Cf_message.t -> [> frame ] * Cf_message.t
+val parse_frame: ?limit:int32 -> Cf_message.t -> [> frame ] * Cf_message.t
 val emit_frame: [< frame ] -> Cf_message.t
 
 (** {5 Errors} *)
 type error =
+    | X_session_aborted
+    | X_transport_error of exn
     | X_frame_bad_syntax
     | X_frame_too_large
     | X_frame_out_of_sequence of header
     method limits: Iom_octet_stream.limits
 end
 
-class ['msg, 'rpy, 'err, 'ans] cprofile:
+class ['msg, 'rpy, 'err, 'ans] chprofile:
     msg:'msg -> rpy:'rpy -> err:'err -> ans:'ans ->
     object
         constraint 'msg = #eprofile
 
 (** {5 Entity I/O} *)
 
-type eijack = {
-  eij_flowTx : Iom_stream.readywait Iom_gadget.tx;
-  eij_eventRx : Mime_stream.entity_scan_event Iom_gadget.rx;
+type iefix = {
+  ief_flowTx : Iom_stream.readywait Iom_gadget.tx;
+  ief_eventRx : Mime_stream.entity_scan_event Iom_gadget.rx;
 }
 
-type eiplug and eostate
+type iepad and oestate
 
-type eojack = {
-  eoj_flowRx : Iom_stream.readywait Iom_gadget.rx;
-  eoj_eventTx : Mime_stream.entity_emit_event Iom_gadget.tx;
+type oefix = {
+  oef_flowRx : Iom_stream.readywait Iom_gadget.rx;
+  oef_eventTx : Mime_stream.entity_emit_event Iom_gadget.tx;
 }
 
-type eoplug and eistate
+type oepad and iestate
 
 (** {5 Message Exchange} *)
 
-type cxrsp =
-    | M_clt_rpy of eijack
-    | M_clt_err of eijack
-    | M_clt_ans of int32 * eijack
+type cxrsp = private
+    | M_clt_rpy of iefix
+    | M_clt_err of iefix
+    | M_clt_ans of int32 * iefix
     | M_clt_nul
 
-type cxjack = {
-    cxj_msgno : int32;
-    cxj_req : eojack;
-    cxj_rspRx : cxrsp Iom_gadget.rx;
-    cxj_failedRx : Iom_stream.failed Iom_gadget.rx;
+type cxfix = private {
+    cxf_msgno : int32;
+    cxf_req : oefix;
+    cxf_rspRx : cxrsp Iom_gadget.rx;
+    cxf_failedRx : Iom_stream.failed Iom_gadget.rx;
 }
 
-type cxplug
+type cxpad
 
 val cx_harness:
-    ('msg, 'rpy, 'err, 'ans) #cprofile -> int32 ->
-    (cxplug * cxjack) Iom_gadget.t
+    ('msg, 'rpy, 'err, 'ans) #chprofile -> int32 ->
+    (cxpad * cxfix) Iom_gadget.t
 
-type sxrsp =
-    | M_srv_rpy of eoplug
-    | M_srv_err of eoplug
-    | M_srv_ans of int32 * eoplug
+type sxrsp = private (* need functions for composing these *)
+    | M_srv_rpy of oepad
+    | M_srv_err of oepad
+    | M_srv_ans of int32 * oepad
     | M_srv_nul
 
-type sxjack = {
-    sxj_msgno : int32;
-    sxj_req : eijack;
-    sxj_rspTx : sxrsp Iom_gadget.tx;
-    sxj_failedRx : Iom_stream.failed Iom_gadget.rx;
+type sxfix = private {
+    sxf_msgno : int32;
+    sxf_req : iefix;
+    sxf_rspTx : sxrsp Iom_gadget.tx;
+    sxf_failedRx : Iom_stream.failed Iom_gadget.rx;
 }
 
-type sxplug
+type sxpad
 
 (** {5 Channel Driver} *)
 
-type cnotify = Iom_stream.failed
+type chnotify = Iom_stream.failed
 
-type cjack = {
-    cj_notifyRx : cnotify Iom_gadget.rx;
-    cj_exchangeRx : sxjack Iom_gadget.rx;
-    cj_exchangeTx : cxplug Iom_gadget.tx;
+type chprofile_basic = (eprofile, eprofile, eprofile, eprofile) chprofile
+
+type chfix = private {
+    chf_notifyRx : chnotify Iom_gadget.rx;
+    chf_exchangeRx : sxfix Iom_gadget.rx;
+    chf_exchangeTx : cxpad Iom_gadget.tx;
 }
 
-type cplug and cstate
+type chpad = private {
+    chp_channo: int32;
+    chp_profile: chprofile_basic;
+    chp_notifyTx: chnotify Iom_gadget.tx;
+    chp_exchangeRx: cxpad Iom_gadget.rx;
+    chp_exchangeTx: sxfix Iom_gadget.tx;
+}
 
-val cstate0: cstate
+type chsrxvariant and chstxvariant
 
-val c_harness:
-    int32 -> ('msg, 'rpy, 'err, 'ans) #cprofile -> (cplug * cjack) Iom_gadget.t
+type chstate = {
+    chs_rxseqno: int32;
+    chs_rxv: chsrxvariant;
+    chs_rxq: cxpad Cf_deque.t;
+    chs_txseqno: int32;
+    chs_txv: chstxvariant;
+    chs_txq: sxpad Cf_deque.t;
+}
 
-val c_failed: cstate -> cplug -> error -> 'a Cf_exnopt.t Iom_gadget.t
+val chs0: chstate
 
-val c_rxflow_guard:
-    cstate -> (int * cstate -> unit Iom_gadget.t) -> unit Iom_gadget.guard
+val ch_harness:
+    int32 -> ('msg, 'rpy, 'err, 'ans) #chprofile ->
+    (chpad * chfix) Iom_gadget.t
 
-val c_txframe_guard:
-    int -> cstate -> cplug ->
-    (int * [> frame ] list * cstate -> unit Iom_gadget.t) ->
+val ch_failed: chstate -> chpad -> error -> 'a Cf_exnopt.t Iom_gadget.t
+
+val ch_rxf_guard:
+    chstate -> (int * chstate -> unit Iom_gadget.t) -> unit Iom_gadget.guard
+
+val ch_txf_guard:
+    int -> chstate -> chpad ->
+    (int * [> frame ] list * chstate -> unit Iom_gadget.t) ->
     unit Iom_gadget.guard
     
-val c_rxframe:
-    cstate -> cplug -> [< frame ] -> (int * cstate) Cf_exnopt.t Iom_gadget.t
+val ch_rxf:
+    chstate -> chpad -> [< frame ] -> (int * chstate) Cf_exnopt.t Iom_gadget.t
 
-val c_txready:
-    int -> cstate -> cplug -> (int * [> frame ] list * cstate) Iom_gadget.t
+val ch_txr:
+    int -> chstate -> chpad -> (int * [> frame ] list * chstate) Iom_gadget.t
 
 (** {5 Session Management} *)
+type scontrol = Iom_stream.stop
+type snotify = Iom_stream.failed
 
-(* type sjack *)
+type sfix = {
+    sp_controlTx: scontrol Iom_gadget.tx;
+    sp_notifyRx: snotify Iom_gadget.rx;
+}
+
+type spad = {
+    sp_controlRx: scontrol Iom_gadget.rx;
+    sp_notifyTx: snotify Iom_gadget.tx;
+}
+
+type sstate
+
+val ss0: sstate
 
 (*--- End of File [ beep_core.mli ] ---*)

beep/beep_serial.ml

   OF THE POSSIBILITY OF SUCH DAMAGE. 
  *---------------------------------------------------------------------------*)
 
+open Cf_cmonad.Op
+
+(**)
+let errj = Cf_journal.stderr
+(**)
+
+(*
 module IOg = Iom_gadget
 module IOs = Iom_stream
 module IO8 = Iom_octet_stream
 module IOn = Iom_sock_stream
 
 module C = Beep_core
+*)
 
+type seq_header = {
+    seq_channo: int32;
+    seq_ackno: int32;
+    seq_window: int32;
+}
+
+type seq = [ `SEQ of seq_header ]
+
+type frame = [ Beep_core.frame | seq ]
+
+let parse_seq_frame =
+    let bad_syntax = Beep_core.Error Beep_core.X_frame_bad_syntax in
+    let too_large = Beep_core.Error Beep_core.X_frame_too_large in
+    let ef _ x = raise (match x with End_of_file -> x | _ -> bad_syntax) in
+    let uint31 n = if Int32.compare n 0l < 0 then raise bad_syntax in
+    let int32_of_maxint = Int32.of_int max_int in
+    fun m ->
+    	let s = Scanf.Scanning.from_function (Cf_message.to_function m) in
+    	Scanf.kscanf s ef "%3[A-Z] %lu %lu %lu\r\n%n"
+            begin fun key ch seq win n ->
+                match key with
+                | "SEQ" ->
+                    uint31 ch;
+                    if Int32.compare win int32_of_maxint > 0 then
+                        raise too_large;
+                    let m = Cf_message.shift ~pos:n m in
+                    let seq = `SEQ {
+                        seq_channo = ch;
+                        seq_ackno = seq;
+                        seq_window = win;
+                    } in
+                    seq, m
+                | _ ->
+                    raise bad_syntax
+            end
+
+let parse_frame ?limit m =
+    try
+        Beep_core.parse_frame ?limit m
+    with
+    | Beep_core.Error _ ->
+        parse_seq_frame m
+
+(*
+let buffer_add_seq_frame b (`SEQ header) =
+    let b = Buffer.create 40 in
+    Printf.bprintf b "SEQ %lu %lu %lu\r\n" header.seq_channo header.seq_ackno
+        header.seq_window;
+    let length = Buffer.length b in
+    [ Buffer.contents b, 0, length ]
+
+let emit_frame = function
+    | #seq as seq -> emit_seq_frame seq
+    | #Beep_core.frame as core -> Beep_core.emit_frame core
+*)
+
+module N32_map = Beep_core.N32_map
 module Int_map = Cf_rbtree.Map(Cf_ordered.Int_order)
 
-type mcplug = {
-    mcp_core: C.cplug;
-    mcp_priority: int;
-    mcp_rxwinlow: int;
-    mcp_rxwinhigh: int;
+type cpad = {
+    cp_core: Beep_core.chpad;
+    cp_priority: int;
+    cp_rxwinlow: int;
+    cp_rxwinhigh: int;
 }
 
-type ctx = {
-    ctx_channo: int32;
-    ctx_window: int;
+type cstate = {
+    cs_core: Beep_core.chstate;
+    cs_rxwindow: int;
+    cs_txwindow: int;
 }
 
-type crx = {
-    crx_channo: int32;
-    crx_ackno: int32;
-    crx_window: int;
+let mwindow0 = 4096 (* RFC 3081, section 3.1.1 *)
+
+let cstate0 = {
+    cs_core = Beep_core.chs0;
+    cs_rxwindow = mwindow0;
+    cs_txwindow = mwindow0;
 }
 
-type state = {
-    s_cmap: (mcplug * C.cstate) C.N32_map.t;
-    s_txq: ctx Cf_deque.t Int_map.t;
-    s_rxq: crx Cf_deque.t Int_map.t;
+(* a serial connection fix *)
+type s8fix = {
+    s8_notifyRx: Iom_stream.flownotify Iom_gadget.rx;
+    s8_controlTx: Iom_stream.flowcontrol Iom_gadget.tx;
+    s8_octetsRx: Iom_octet_stream.fragment Iom_gadget.rx;
+    s8_octetsTx: Iom_octet_stream.fragment Iom_gadget.tx;
 }
 
+(* convert a socket endpoint fix into a serial connection fix *)
+let to_s8fix (fix : Iom_sock_stream.endpoint_fix) =
+    let ((octetsRx, octetsTx), (notifyRx, controlTx)) = fix in {
+        s8_notifyRx = notifyRx;
+        s8_controlTx = controlTx;
+        s8_octetsRx = octetsRx;
+        s8_octetsTx = octetsTx;
+    }
+
+type sstate = {
+    ss_core: Beep_core.sstate;
+    ss_s8rxfin: bool;
+    ss_s8txblock: int option;
+    ss_csm: cstate N32_map.t;
+    ss_cpqm: cpad Cf_deque.t Int_map.t;
+}