From ebaf7de91d66eddf1e9db532c3e03ad83aa4b91d Mon Sep 17 00:00:00 2001 From: sc Date: Fri, 22 Dec 2000 10:20:40 +0000 Subject: Further developement of object emission --- comm/ObexStream.cc | 160 +++++++++++++++++++++++++++++++++++++++-------------- comm/ObexStream.h | 12 +++- 2 files changed, 129 insertions(+), 43 deletions(-) diff --git a/comm/ObexStream.cc b/comm/ObexStream.cc index d70caa1..1c0f8fc 100644 --- a/comm/ObexStream.cc +++ b/comm/ObexStream.cc @@ -13,13 +13,15 @@ */ #include "ObexStream.h" +#include "SignalHandler.h" #include "error.h" #include #include -IvlObexStream :: IvlObexStream (IvlAddress* a, IvlBaseScheduler* mpx) -: IvlStream (a) +IvlObexStream :: IvlObexStream (IvlAddress* a, sword mps, IvlBaseScheduler* mpx) +: IvlStream (a), + MaxPacketSize (mps) { if (Listen () < 0) { SysError (ErrWarn, "IvlObexStream::IvlObexStream: Listen"); @@ -45,15 +47,11 @@ IvlObexStream :: HandleRead () IvlObexAgent* cl = new IvlObexAgent (fd, this); } -#if 0 -void -IvlObexStream :: DiscoverDevices () -{ -} -#endif /******************************************************************************/ +#define MAX_IN_SIZE 1024 + /* OBEX request codes */ #define OBEX_FINAL_BIT 0x80 #define OBEX_CONNECT_REQ 0x00 @@ -111,7 +109,7 @@ IvlObexStream :: DiscoverDevices () #define OBEX_HEADER_RESPONSE 0x0e /* Auth. response */ #define OBEX_HEADER_CLASS 0x0f /* Object class */ - +#if 0 class IvlObexHeader { public: byte Hi; @@ -120,16 +118,22 @@ public: void* Buf; IvlObexHeader (byte hi, lword l, lword o) : Hi (hi), Length (l), Offset (o) {} }; +#endif + +enum status { Waiting, Connecting, Sending }; IvlObexAgent :: IvlObexAgent (int fd, IvlObexStream* l) : IvlBufStream (), MyLink (l), - CurObj (0) + CurObj (0), + Status (Waiting) { SetMode (IORead); IvlChannel::Open (fd); Add (l->GetScheduler ()); - OutSize = 255; + int max_out = l->MaxPacketSize; + OutputBuffer (max_out +128, 128, max_out + 128, max_out) ; + InputBuffer (MAX_IN_SIZE, 128, MAX_IN_SIZE + 128); } /* this is a problem: how do I make sure that agents created this way (after a @@ -138,7 +142,8 @@ the situation with Ivy agents. */ IvlObexAgent :: IvlObexAgent (IvlAddress* a, IvlObexStream* l) : IvlBufStream (0, a), MyLink (l), - CurObj (0) + CurObj (0), + Status (Waiting) { if (!Setup ()) { cerr << "Obex warning. Cannot set up stream: "; @@ -147,7 +152,9 @@ IvlObexAgent :: IvlObexAgent (IvlAddress* a, IvlObexStream* l) } SetMode (IORead); Add (l->GetScheduler ()); - OutSize = 255; + int max_out = l->MaxPacketSize; + OutputBuffer (max_out +128, 128, max_out + 128, max_out) ; + InputBuffer (MAX_IN_SIZE, 128, MAX_IN_SIZE + 128); } IvlObexAgent :: ~IvlObexAgent () @@ -158,10 +165,33 @@ IvlObexAgent :: ~IvlObexAgent () void IvlObexAgent :: HandleRead () { - if (ReadInput () <= 0) { +#if 1 + int n = ReadInput (); + if (n <= 0) { /* could emit a OBEX_EV_LINKERR event to the upper software layers */ + cerr << "connection was interrupted\n"; return; } +#else + /* This is here because IRDA sockets seem to spuriously announce they have + data available. Faudra en reprendre des bouts dans BufStream et Channel. */ + + /* read in buffer */ + InBuffer.NeedSize (1); + int n = recv (Fd, (void*) InBuffer.Free (), 1, MSG_PEEK); + if (n > 0) { + n = recv (Fd, (void*) InBuffer.Free (), InBuffer.FreeLength (), 0); + InBuffer.More (n); + } else if (n == 0) { +// cerr << "no data!?\n"; + return; + } else { + /* could emit a OBEX_EV_LINKERR event to the upper software layers */ + cerr << "connection was interrupted\n"; + return; + } +#endif + cerr << "read " << n << " bytes\n"; /* if not enough data for reading packet length, wait for future input */ if (InBuffer.BufLength () < 3) @@ -176,7 +206,6 @@ IvlObexAgent :: HandleRead () return; - /* should add tests depending on what we are expecting */ /* read operation code and skip packet length */ byte reqcode; @@ -187,6 +216,8 @@ IvlObexAgent :: HandleRead () bool final = reqcode & OBEX_FINAL_BIT; reqcode = reqcode & ~OBEX_FINAL_BIT; + /* should complete status-based tests!!! */ + switch (reqcode) { case OBEX_CONNECT_REQ: ParseConnect (len, final); @@ -209,6 +240,9 @@ IvlObexAgent :: HandleRead () case OBEX_CONTINUE_RSP: cerr << "--> continue.\n"; ParseHeaders (len, final); + if (Status == Sending) { + Status = Waiting; + } break; case OBEX_SWITCH_PRO_RSP: cerr << "--> switch protocol.\n"; @@ -217,6 +251,11 @@ IvlObexAgent :: HandleRead () case OBEX_SUCCESS_RSP: cerr << "--> success.\n"; ParseHeaders (len, final); + if (Status == Connecting) { + KeepSending (); + } else if (Status == Sending) { + Status = Waiting; + } break; case OBEX_CREATED_RSP: cerr << "--> created.\n"; @@ -318,7 +357,9 @@ IvlObexAgent :: ParseConnect (sword len, bool final) InBuffer.ReadByte (version); InBuffer.ReadByte (flags); InBuffer.ReadShort (max_packet_length); - OutSize = ntohs (max_packet_length); + max_packet_length = ntohs (max_packet_length); + if (OutSize > max_packet_length) + OutSize = max_packet_length; cerr << "--> connect: version " << (version >> 4) << "." << (version & 0x0f) << ", " << OutSize << " bytes packets max\n"; @@ -335,9 +376,8 @@ IvlObexAgent :: ParseConnect (sword len, bool final) OutBuffer.WriteShort (htons (7)); OutBuffer.WriteByte (OBEX_VERSION); OutBuffer.WriteByte (0); - OutBuffer.WriteShort (htons (1024)); - SendResponse (); - + OutBuffer.WriteShort (htons (MAX_IN_SIZE)); + Flush (); } void @@ -347,8 +387,8 @@ IvlObexAgent :: ParseDisconnect (sword len, bool final) InBuffer.Flush (); OutBuffer.WriteByte (OBEX_SUCCESS_RSP | OBEX_FINAL_BIT); OutBuffer.WriteShort (htons (3)); - SendResponse (); - OutSize = 255; + Flush (); + OutSize = MyLink->MaxPacketSize; } void @@ -356,6 +396,7 @@ IvlObexAgent :: ParseAbort (sword len, bool final) { cerr << "--> abort.\n"; InBuffer.Flush (); + Status = Waiting; } void @@ -366,7 +407,7 @@ IvlObexAgent :: ParsePut (sword len, bool final) byte rsp = final ? OBEX_SUCCESS_RSP : OBEX_CONTINUE_RSP; OutBuffer.WriteByte (rsp | OBEX_FINAL_BIT); OutBuffer.WriteShort (htons (3)); - SendResponse (); + Flush (); } void @@ -498,21 +539,17 @@ IvlObexAgent :: ParseHeaders (sword, bool) and deliver OBEX_EV_PARSEERR to upper soft layers*/ } -void -IvlObexAgent :: SendResponse () -{ - Flush (); -} void -IvlObexAgent :: SendHeader (byte hi, byte encoding, const char* hv) +IvlObexAgent :: SendHeader (byte hi, byte encoding, const char* hv, int len) { + IvlSignalBlocker b (SigPipe); + OutBuffer.WriteByte (hi | encoding); switch (encoding) { case OBEX_UNICODE_HDR: { - int len = 2 * (strlen (hv) + 1); OutBuffer.WriteShort (htons (3 + len)); byte buf[len]; byte* p = buf; @@ -528,7 +565,6 @@ IvlObexAgent :: SendHeader (byte hi, byte encoding, const char* hv) break; case OBEX_STRING_HDR: { - int len = strlen (hv) + 1; OutBuffer.WriteShort (htons (3 + len)); OutBuffer.WriteBuf ((const byte*) hv, len); break; @@ -543,25 +579,63 @@ IvlObexAgent :: SendHeader (byte hi, byte encoding, const char* hv) } +/* tout ce qui suit serait a reecrire si on avait d'autres headers possibles */ void IvlObexAgent :: SendObject (IvlObexObject& o) { - /* faudrait d'abord envoyer la connexion ! */ - OutBuffer.WriteByte (OBEX_PUT_REQ | OBEX_FINAL_BIT); - int l = 3 + (1 + 4) + (3 + 2 * (strlen (o.Name) + 1)) + (3 + strlen (o.Body) + 1); - OutBuffer.WriteShort (htons (l));// FIXME!!!! + /* faudrait p'tet d'abord envoyer la connexion et mettre status = connecting ! */ + /* faudrait aussi traiter les cas ou ca doit absolument tenir en un paquet */ + + /* plein de calculs prealables pour savoir combien on va envoyer en fait */ + int len = 3; + int class_len = o.Class ? (1 + 4) : 0; + int name_len = o.Name ? (3 + 2 * (strlen (o.Name) + 1)) : 0; + int descr_len = o.Description ? (3 + 2 * (strlen (o.Description) + 1)) : 0; + int body_len = o.Body ? (3 + strlen (o.Body) + 1) : 0; + bool send_descr = false; + bool send_all_body; + + if (len + class_len + name_len > OutSize) { + cerr << "object name is longer than packet size!\n"; + return; + } + len += (class_len + name_len); + + if (len + descr_len > OutSize) + goto send; + send_descr = true; + len += descr_len; + + + if (len + body_len <= OutSize) { + len += body_len; + send_all_body = true; + } else + len = OutSize; + + cerr << len << " bytes\n"; + +send: + OutBuffer.WriteByte (OBEX_PUT_REQ | (send_all_body ? OBEX_FINAL_BIT : 0)); + OutBuffer.WriteShort (htons (len)); if (o.Class) - SendHeader (OBEX_HEADER_CLASS, OBEX_INT_HDR, (const char*) o.Class); + SendHeader (OBEX_HEADER_CLASS, OBEX_INT_HDR, (const char*) o.Class, 0); if (o.Name) - SendHeader (OBEX_HEADER_NAME, OBEX_UNICODE_HDR, o.Name); + SendHeader (OBEX_HEADER_NAME, OBEX_UNICODE_HDR, o.Name, name_len - 3); if (o.Description) - SendHeader (OBEX_HEADER_DESCRIPTION, OBEX_STRING_HDR, o.Description); - + if (send_descr) + SendHeader (OBEX_HEADER_DESCRIPTION, OBEX_STRING_HDR, o.Description, descr_len - 3); + else + ; // enregistrer + if (o.Body) - SendHeader (OBEX_HEADER_BODY_END, OBEX_STRING_HDR, o.Body); + if (send_all_body) + SendHeader (OBEX_HEADER_BODY_END, OBEX_STRING_HDR, o.Body, body_len - 3); + else + ; // enregistrer #if 0 @@ -573,7 +647,13 @@ IvlObexAgent :: SendObject (IvlObexObject& o) OutBuffer.WriteShort (htons (3)); SendHeader (OBEX_HEADER_BODY_END, 0); #endif - SendResponse (); + Flush (); + Status = Sending; +} + +void +IvlObexAgent :: KeepSending () +{ } diff --git a/comm/ObexStream.h b/comm/ObexStream.h index 6e83013..3c0caad 100644 --- a/comm/ObexStream.h +++ b/comm/ObexStream.h @@ -24,12 +24,17 @@ class IvlAddress; #include "BufStream.h" #include "Event.h" +#define OBEX_MIN_PACKET 255 class IvlObexStream : public IvlStream { +friend class IvlObexAgent; + +protected: + sword MaxPacketSize; public: IvlTrigger NewAgents; - IvlObexStream (IvlAddress*, IvlBaseScheduler* = IvlScd); + IvlObexStream (IvlAddress*, sword = OBEX_MIN_PACKET, IvlBaseScheduler* = IvlScd); ~IvlObexStream (); IvlChannel* Copy () const; @@ -44,6 +49,7 @@ private: IvlObexStream* MyLink; void* CurObj; IvlListOf OutHeaders; + int Status; void HandleRead (); void ParseConnect (sword, bool); @@ -53,8 +59,8 @@ private: void ParseGet (sword, bool); void ParseSetPath (sword, bool); void ParseHeaders (sword, bool); - void SendResponse (); - void SendHeader (byte, byte, const char*); + void KeepSending (); + void SendHeader (byte, byte, const char*, int); public: IvlObexAgent (int, IvlObexStream*); -- cgit v1.1