;;; -*- Mode:Common-Lisp; Package:IP; Base:10; Fonts:(COURIER TR12I TR12BI TR12 MEDFNTB); Patch-file:T -*-

;1 FIle name: UDP-STREAM.LISP*
;1 Lets the UDP-STREAM medium know about the UNIX stream type*
;1 Started 3-7-1989 by Eric Karlson, UC-Berkeley under Robert Wilensky*
;1 Phone: (415) 642-9076, E-mail Address: karlson@ucbarpa.berkeley.edu*

;1------------------------------------------------------------*
;1 Let the UDP-STREAM medium know about the UNIX streams*
;1------------------------------------------------------------*

(defun 4make-udp-stream* (port-object &key host (remote-port 0) (remote-address 0)
			  (direction :bidirectional) (characters t) (timeout 10)
			  &aux host-name)
"2Create a UDP stream object.
PORT-OBJECT The UDP port object.
:HOST (OPTIONAL) The host to 'connect' to.  May be a name, IP address, or host object.  If nil, the open is passive (listen).
:REMOTE-PORT (Optional) The remote UDP port on the specified host.  May be 0 (default) for passive opens.
:REMOTE-ADDRESS (used only if :host is nil)  IP address of the remote host. 
:DIRECTION (Optional) :Input, :output, or :bidirectional (default).
:CHARACTERS (Optional) Either t (characters, the default), nil (binary), or :ascii (ascii characters).
:TIMEOUT  (Optional) The timeout (in seconds) used in :next-input-buffer.
  Nil indicates no timeout.  Default is 10 seconds.*"
  (declare (function make-udp-stream (INSTANCE &key T FIXNUM FIXNUM KEYWORD T FIXNUM &aux net:HOST) STREAM)
	   (values UDP-STREAM))
  (setf (send port-object :receive-timeout) timeout)
  (when host
    (setf host (parse-ip-host-spec host))
    (setf host-name (send host :short-name))	      
    (setf remote-address (first (closest-addresses-to-network (get-ip-addresses host)))))
  (case direction
    (:INPUT
     (make-instance
       (cond
	 ((eq characters :ASCII) 'udp-ascii-translating-input-character-stream)
	 ((eq characters :UNIX) 'unix-translating-input-character-stream)
	 (characters 'udp-input-character-stream)
	 (t 'udp-input-binary-stream))
       :port port-object
       :source-port (send port-object :port-number) :source-address (closest-local-address remote-address)
       :destination-port remote-port :destination-address remote-address))
    (:OUTPUT
     (make-instance
       (cond
	 ((eq characters :ASCII) 'udp-ascii-translating-output-character-stream)
	 ((eq characters :UNIX) 'unix-translating-output-character-stream)
	 (characters 'udp-output-character-stream)
	 (t 'udp-output-binary-stream))
       :port port-object
       :source-port (send port-object :port-number) :source-address (closest-local-address remote-address)
       :destination-port remote-port :destination-address remote-address))
    (:bidirectional
     (make-instance
       (cond
	 ((eq characters :ASCII) 'udp-ascii-translating-character-stream)
	 ((eq characters :UNIX) 'unix-translating-character-stream)
	 (characters 'udp-character-stream)
	 (t 'udp-binary-stream))
       :port port-object
       :source-port (send port-object :port-number) :source-address (closest-local-address remote-address)
       :destination-port remote-port :destination-address remote-address))))

;1-------------------------------------------------*
;1 Let the TCP-STREAM medium know about UNIX*
;1-------------------------------------------------*

(net:define-stream-type 4:unix-translating-input-character-stream *'(:input :unix) :udp-stream)
(net:define-stream-type 4:unix-translating-output-character-stream *'(:output :unix) :udp-stream)
(net:define-stream-type 4:unix-translating-character-stream *'(:bidirectional :unix) :udp-stream)