Branch: Tag:

2004-02-26

2004-02-26 22:54:47 by Marcus Comstedt <marcus@mc.pp.se>

Documentation.

Rev: lib/modules/Protocols.pmod/OBEX.pmod:1.4

1:      #pike __REAL_VERSION__    - //! OBEX, the OBject EXchange protocol. Originally specified by the - //! IrDA (Infrared Data Association). This module can be used to - //! transfer MIDI file with the opening song from Sailer Moon to a - //! mobile phone. + //! The IrDA┬« Object Exchange Protocol. + //! OBEX is a protocol for sending and receiving binary objects + //! to mobile devices using transports such as IR and Bluetooth.    -  + //! A request opcode, for use with the @[client.do_request()] function.   enum Request { -  REQ_CONNECT = 0x80, -  REQ_DISCONNECT = 0x81, -  REQ_PUT = 0x02, -  REQ_GET = 0x03, -  REQ_SETPATH = 0x85, -  REQ_SESSION = 0x87, -  REQ_ABORT = 0xff, +  REQ_CONNECT = 0x80, //! Establish a new OBEX connection +  REQ_DISCONNECT = 0x81, //! Terminate an OBEX connection +  REQ_PUT = 0x02, //! Send an object to the mobile device +  REQ_GET = 0x03, //! Receive an object from the mobile devuce +  REQ_SETPATH = 0x85, //! Change the working directory +  REQ_SESSION = 0x87, //! Manage a session +  REQ_ABORT = 0xff, //! Abort the request currently being processed    -  +  //! For @[REQ_PUT] and @[REQ_GET] requests, REQ_FINAL must be set +  //! for the request block containing the last portion of the headers. +  //! Other requests must be sent as a single block and have the REQ_FINAL +  //! bit encoded in their request opcode.    REQ_FINAL = 0x80   };    -  + //! An identifier for a request or response header   enum HeaderIdentifier { -  HI_COUNT = 0xc0, -  HI_NAME = 0x01, -  HI_TYPE = 0x42, -  HI_LENGTH = 0xc3, -  HI_TIME = 0x44, -  HI_DESCRIPTION = 0x05, -  HI_TARGET = 0x46, -  HI_HTTP = 0x47, -  HI_BODY = 0x48, -  HI_ENDOFBODY = 0x49, -  HI_WHO = 0x4a, -  HI_CONNID = 0xcb, -  HI_APPPARAM = 0x4c, -  HI_AUTHCHALL = 0x4d, -  HI_AUTHRESP = 0x4e, -  HI_CREATORID = 0xcf, -  HI_WANUUID = 0x50, -  HI_OBJCLASS = 0x51, -  HI_SESSPARAM = 0x52, -  HI_SESSSEQNR = 0x93, +  HI_COUNT = 0xc0, //! Number of objects to transfer (used by @[REQ_CONNECT]) +  HI_NAME = 0x01, //! Name of the object (string) +  HI_TYPE = 0x42, //! Type of the object (IANA media type) +  HI_LENGTH = 0xc3, //! Length of the object transferred, in octets +  HI_TIME = 0x44, //! ISO 8601 timestamp (string) +  HI_DESCRIPTION = 0x05,//! Text description of the object +  HI_TARGET = 0x46, //! Name of service that operation is targeted to +  HI_HTTP = 0x47, //! Any HTTP 1.x header +  HI_BODY = 0x48, //! A chunk of the object body +  HI_ENDOFBODY = 0x49, //! The final chunk of the object body +  HI_WHO = 0x4a, //! Identifies the OBEX application (string) +  HI_CONNID = 0xcb, //! An identifier used for OBEX connection multiplexing +  HI_APPPARAM = 0x4c, //! Extended application request & response information +  HI_AUTHCHALL = 0x4d, //! Authentication digest-challenge +  HI_AUTHRESP = 0x4e, //! Authentication digest-response +  HI_CREATORID = 0xcf, //! Indicates the creator of an object +  HI_WANUUID = 0x50, //! Uniquely identifies the OBEX server +  HI_OBJCLASS = 0x51, //! OBEX object class of object +  HI_SESSPARAM = 0x52, //! Parameters used in session commands/responses +  HI_SESSSEQNR = 0x93, //! Sequence number used in each OBEX packet for reliability   };    -  + //! A flag for the @[REQ_SETPATH] command indicating that the + //! parent directory should be selected   constant SETPATH_BACKUP = 1; -  +  + //! A flag for the @[REQ_SETPATH] command indicating that the + //! selected directory should not be created if it doesn't exist   constant SETPATH_NOCREATE = 2;    -  + //! A set of request or response headers. Each HI can be associated + //! with either a single value (int or string, depending on the HI in + //! question) or an array with multiple such values.   typedef mapping(HeaderIdentifier:string|int|array) Headers;    -  +  + //! Serialize a set of headers to wire format + //! + //! @seealso + //! @[split_headers()] + //!   string encode_headers(Headers h)   {    string r0 = "", r = "";
74:    return r0+r;   }    + //! Deserialize a set of headers from wire format + //!   Headers decode_headers(string h)   {    Headers r = ([]);
117:    return r;   }    + //! Given a set of headers in wire format, divide them into + //! portions of no more than @[chunklen] octets each (if possible). + //! No individual header definition will be split into two portions. + //!   array(string) split_headers(string h, int chunklen)   {    string acc = "";
151:    return r + (sizeof(acc) || !sizeof(r)? ({ acc }) : ({ }));   }    +  + //! An OBEX client + //! + //! @seealso + //! @[ATclient] + //!   class client   {    static Stdio.Stream con;
162:       static int server_version, server_connect_flags, max_pkt_length = 255;    +  +  //! Perform a request/response exchange with the server. +  //! No interpretation is preformed of either the request or +  //! response data, they are just passed literally. +  //! +  //! @param r +  //! Request opcode +  //! @param data +  //! Raw request data +  //! +  //! @returns +  //! An array with the response information +  //! +  //! @array +  //! @elem int returncode +  //! An HTTP response code +  //! @elem string data +  //! Response data, if any +  //! @endarray +  //! +  //! @seealso +  //! @[do_request()] +  //!    array(int|string) low_do_request(Request r, string data)    {    if(3+sizeof(data) > max_pkt_length)
186:    return ({ (rc>>4)*100+(rc&15), rdata });    }    +  //! Perform a request/response exchange with the server, +  //! including processing of headers and request splitting. +  //! +  //! @param r +  //! Request opcode +  //! @param headers +  //! Request headers +  //! @param extra_req +  //! Any request data that should appear before the headers, +  //! but after the opcode +  //! +  //! @returns +  //! An array with the response information +  //! +  //! @array +  //! @elem int returncode +  //! An HTTP response code +  //! @elem Headers headers +  //! Response headers +  //! @endarray +  //! +  //! @seealso +  //! @[low_do_request()], @[do_abort()], @[do_put()], @[do_get()], +  //! @[do_setpath()], @[do_session()] +  //!    array(int|Headers) do_request(Request r, Headers|void headers,    string|void extra_req)    {
212:    return ({ rc, (rc==501? ([]): decode_headers(rdata)) });    }    +  //! Perform a @[REQ_ABORT] request. +  //! +  //! @seealso +  //! @[do_request()] +  //!    array(int|Headers) do_abort(Headers|void headers)    {    [int rc, Headers h] = do_request(REQ_ABORT, headers);
220:    return ({ rc, h });    }    +  //! Perform a @[REQ_PUT] request. +  //! +  //! @param data +  //! Body data to send, or a stream to read the data from +  //! @param extra_headers +  //! Any additional headers to send (@[HI_LENGTH] and @[HI_BODY] +  //! are generated by this function) +  //! +  //! @seealso +  //! @[do_get()], @[do_request()] +  //!    array(int|Headers) do_put(string|Stdio.Stream data,    Headers|void extra_headers)    {
248:    return ({ rc, h });    }    +  //! Perform a @[REQ_GET] request. +  //! +  //! @param data +  //! A stream to write the body data to +  //! @param headers +  //! Headers for the request +  //! +  //! @returns +  //! See @[do_request()]. The Headers do not contain any @[HI_BODY] +  //! headers, they are written to the @[data] stream. +  //! +  //! @seealso +  //! @[do_put()], @[do_request()] +  //!    array(int|Headers) do_get(Stdio.Stream data,    Headers|void headers)    {
268:    return ({ rc, h });    }    +  //! Perform a @[REQ_SETPATH] request. +  //! +  //! @param path +  //! The directory to set as current working directory +  //! @string +  //! @value "/" +  //! Go to the root directory +  //! @value ".." +  //! Go to the parent directory +  //! @endstring +  //! @param flags +  //! Logical or of zero or more of @[SETPATH_BACKUP] and @[SETPATH_NOCREATE] +  //! @param extra_headers +  //! Any additional request headers (the @[HI_NAME] header is generated +  //! by this function) +  //! +  //! @seealso +  //! @[do_request()] +  //!    array(int|Headers) do_setpath(string path, int|void flags,    Headers|void extra_headers)    {
281:    sprintf("%c%c", flags, 0));    }    +  //! Perform a @[REQ_SESSION] request. +  //! +  //! @seealso +  //! @[do_request()] +  //!    array(int|Headers) do_session(Headers|void headers)    {    return do_request(REQ_SESSION, headers);    }    -  +  //! Establish a new connection using the @[REQ_CONNECT] opcode to +  //! negotiate transfer parameters +  //! +  //! @returns +  //! If the connection succeeds, 1 is returned. Otherwise, 0 is returned. +  //!    int(0..1) connect()    {    if(connected)
312:    return 1;    }    +  //! Terminate a connection using the @[REQ_DISCONNECT] opcode +  //! +  //! @returns +  //! If the disconnection succeeds, 1 is returned. Otherwise, 0 is returned. +  //!    int(0..1) disconnect()    {    if(!connected)
336:    disconnect();    }    +  //! Initialize the client by establishing a connection to the +  //! server at the other end of the provided transport stream +  //! +  //! @param _con +  //! A stream for writing requests and reading back responses. +  //! Typically this is some kind of serial port. +  //!    static void create(Stdio.Stream _con)    {    con = _con;
346:   }       + //! An extension of the @[client] which uses the AT*EOBEX modem command + //! to enter OBEX mode. Use together with Sony Ericsson data cables. + //!   class ATclient   {    inherit client;