X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsymbian%2Fsilcsymbiansocketstream.cpp;h=b2362784d370746515bb6a6ce3d28abbdee303d1;hb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;hp=3fcb7cec500f3e7af52aa33b32c511810408ea5d;hpb=690216574e05c9dcc1e78d6677d4cc82c3d8baa8;p=silc.git diff --git a/lib/silcutil/symbian/silcsymbiansocketstream.cpp b/lib/silcutil/symbian/silcsymbiansocketstream.cpp index 3fcb7cec..b2362784 100644 --- a/lib/silcutil/symbian/silcsymbiansocketstream.cpp +++ b/lib/silcutil/symbian/silcsymbiansocketstream.cpp @@ -1,3 +1,4 @@ + /* silcsymbiansocketstream.cpp @@ -48,8 +49,10 @@ public: /* Send data */ void Send(const TDesC8& buf, TSockXfrLength& ret_len) { + SILC_LOG_DEBUG(("Send()")); s->sock->Send(buf, 0, iStatus, ret_len); - SetActive(); + if (!IsActive()) + SetActive(); } /* Send data */ @@ -59,17 +62,22 @@ public: TInetAddr remote; TBuf<64> tmp; + SILC_LOG_DEBUG(("Send()")); + remote = TInetAddr(remote_port); tmp = (TText *)remote_ip; if (remote.Input(tmp) == KErrNone) { s->sock->SendTo(buf, remote, 0, iStatus, ret_len); - SetActive(); + if (!IsActive()) + SetActive(); } } /* Sending callback */ virtual void RunL() { + SILC_LOG_DEBUG(("RunL(), iStatus=%d", iStatus)); + if (iStatus != KErrNone) { if (iStatus == KErrEof) s->eof = 1; @@ -79,9 +87,12 @@ public: } /* Call stream callback */ - if (s->stream && s->stream->notifier) - s->stream->notifier(s->stream, SILC_STREAM_CAN_WRITE, - s->stream->notifier_context); + if (s->would_block) { + s->would_block = 0; + if (s->stream && s->stream->notifier) + s->stream->notifier(s->stream, SILC_STREAM_CAN_WRITE, + s->stream->notifier_context); + } } /* Cancel */ @@ -112,32 +123,49 @@ public: /* Read data */ void Read() { - if (!s->stream || s->stream->connected) - s->sock->RecvOneOrMore(inbuf, 0, iStatus, inbuf_len); + SILC_LOG_DEBUG(("Read()")); + + if (s->stream && s->stream->connected) + s->sock->RecvOneOrMore(inbuf, 0, iStatus, read_len); else s->sock->RecvFrom(inbuf, remote, 0, iStatus); - SetActive(); + + if (!IsActive()) + SetActive(); } /* Reading callback */ virtual void RunL() { + SILC_LOG_DEBUG(("RunL(), iStatus=%d", iStatus)); + if (iStatus != KErrNone) { if (iStatus == KErrEof) s->eof = 1; else s->error = 1; + + /* Call stream callback */ + if (s->stream && s->stream->notifier) + s->stream->notifier(s->stream, SILC_STREAM_CAN_READ, + s->stream->notifier_context); return; } - if (!inbuf_ptr) - inbuf_ptr = inbuf.Ptr(); - inbuf_len = inbuf.Length(); + if (!s->stream || s->stream->connected) + inbuf_len = read_len(); + else + inbuf_len = inbuf.Length(); - /* Call stream callback */ - if (s->stream && s->stream->notifier) - s->stream->notifier(s->stream, SILC_STREAM_CAN_READ, - s->stream->notifier_context); + if (inbuf_len) { + inbuf_ptr = inbuf.Ptr(); + while (inbuf_ptr) { + /* Call stream callback until all has been read */ + if (s->stream && s->stream->notifier) + s->stream->notifier(s->stream, SILC_STREAM_CAN_READ, + s->stream->notifier_context); + } + } /* Read more */ Read(); @@ -151,7 +179,8 @@ public: TBuf8<8192> inbuf; const unsigned char *inbuf_ptr; - TSockXfrLength inbuf_len; + TInt inbuf_len; + TSockXfrLength read_len; SilcSymbianSocket *s; TInetAddr remote; }; @@ -169,11 +198,14 @@ SilcSymbianSocket *silc_create_symbian_socket(RSocket *sock, stream->sock = sock; stream->ss = ss; + SILC_LOG_DEBUG(("Create new Symbian socket %p", stream)); + stream->send = new SilcSymbianSocketSend; if (!stream->send) { silc_free(stream); return NULL; } + stream->send->s = stream; stream->receive = new SilcSymbianSocketReceive; if (!stream->receive) { @@ -181,12 +213,17 @@ SilcSymbianSocket *silc_create_symbian_socket(RSocket *sock, silc_free(stream); return NULL; } + stream->receive->s = stream; + stream->receive->inbuf_ptr = NULL; + stream->receive->inbuf_len = 0; return stream; } /***************************** SILC Stream API ******************************/ +extern "C" { + /* Stream read operation */ int silc_socket_stream_read(SilcStream stream, unsigned char *buf, @@ -197,23 +234,37 @@ int silc_socket_stream_read(SilcStream stream, unsigned char *buf, SilcSymbianSocketReceive *recv = s->receive; int len; - if (s->error || !s->stream) + SILC_LOG_DEBUG(("Reading from sock %p", s)); + + if (s->error || !s->stream) { + SILC_LOG_DEBUG(("Error reading from sock %p", s)); return -2; - if (s->eof) + } + if (s->eof) { + SILC_LOG_DEBUG(("EOF from sock %p", s)); return 0; - if (!recv->inbuf_len() || !recv->inbuf_ptr) + } + if (!recv->inbuf_len || !recv->inbuf_ptr) { + SILC_LOG_DEBUG(("Cannot read now from sock %p", s)); return -1; + } - len = recv->inbuf_len(); + len = recv->inbuf_len; if (buf_len < len) len = buf_len; /* Copy the read data */ memcpy(buf, recv->inbuf_ptr, len); - recv->inbuf_ptr = NULL; - if (len < recv->inbuf_len()) + if (len < recv->inbuf_len) { recv->inbuf_ptr += len; + recv->inbuf_len -= len; + } else { + recv->inbuf_ptr = NULL; + recv->inbuf_len = 0; + } + + SILC_LOG_DEBUG(("Read %d bytes", len)); return len; } @@ -229,18 +280,30 @@ int silc_socket_stream_write(SilcStream stream, const unsigned char *data, TSockXfrLength ret_len; TPtrC8 write_buf(data, data_len); - if (s->would_block) - return -1; - if (s->error || !s->stream) + SILC_LOG_DEBUG(("Writing to sock %p", s)); + + if (s->error || !s->stream) { + SILC_LOG_DEBUG(("Error writing to sock %p", s)); return -2; - if (s->eof) + } + if (s->eof) { + SILC_LOG_DEBUG(("EOF from sock %p", s)); return 0; + } + if (s->would_block) { + SILC_LOG_DEBUG(("Cannot write now to sock %p", s)); + return -1; + } /* Send data */ send->Send(write_buf, ret_len); if (send->iStatus.Int() != KErrNone) { - if (send->iStatus.Int() == KErrEof) + if (send->iStatus.Int() == KErrEof) { + SILC_LOG_DEBUG(("EOF from sock %p", s)); return 0; + } + SILC_LOG_DEBUG(("Error writing to sock %p, error %d", s, + send->iStatus.Int())); return -2; } @@ -251,6 +314,8 @@ int silc_socket_stream_write(SilcStream stream, const unsigned char *data, if (ret_len() < data_len) s->would_block = 1; + SILC_LOG_DEBUG(("Wrote %d bytes", ret_len())); + return ret_len(); } @@ -290,19 +355,23 @@ int silc_net_udp_receive(SilcStream stream, char *remote_ip_addr, if (s->eof) return 0; - if (!recv->inbuf_len() || !recv->inbuf_ptr) + if (!recv->inbuf_len || !recv->inbuf_ptr) return -1; - len = recv->inbuf_len(); + len = recv->inbuf_len; if (buf_len < len) len = buf_len; /* Copy the read data */ memcpy(buf, recv->inbuf_ptr, len); - recv->inbuf_ptr = NULL; - if (len < recv->inbuf_len()) + if (len < recv->inbuf_len) { recv->inbuf_ptr += len; + recv->inbuf_len -= len; + } else { + recv->inbuf_ptr = NULL; + recv->inbuf_len = 0; + } if (remote_ip_addr && remote_ip_addr_size && remote_port) { TBuf<64> ip; @@ -368,6 +437,8 @@ void silc_socket_stream_destroy(SilcStream stream) SilcSocketStream socket_stream = (SilcSocketStream)stream; SilcSymbianSocket *s = (SilcSymbianSocket *)socket_stream->sock; + SILC_LOG_DEBUG(("Destroying sock %p", s)); + silc_socket_stream_close(stream); silc_free(socket_stream->ip); silc_free(socket_stream->hostname); @@ -384,14 +455,16 @@ void silc_socket_stream_destroy(SilcStream stream) /* Sets stream notification callback for the stream */ -void silc_socket_stream_notifier(SilcStream stream, - SilcSchedule schedule, - SilcStreamNotifier callback, - void *context) +SilcBool silc_socket_stream_notifier(SilcStream stream, + SilcSchedule schedule, + SilcStreamNotifier callback, + void *context) { SilcSocketStream socket_stream = (SilcSocketStream)stream; SilcSymbianSocket *s = (SilcSymbianSocket *)socket_stream->sock; + SILC_LOG_DEBUG(("Setting stream notifier for sock %p", s)); + if (callback) s->stream = socket_stream; else @@ -400,4 +473,12 @@ void silc_socket_stream_notifier(SilcStream stream, socket_stream->notifier = callback; socket_stream->notifier_context = context; socket_stream->schedule = schedule; + + /* Schedule for receiving data by doing one read operation */ + if (callback) + s->receive->Read(); + + return TRUE; } + +} /* extern "C" */