debug outputs.
AUTOMAKE_OPTIONS = 1.0 no-dependencies foreign
+EXTRA_DIST = *.cpp *.h
+
include $(top_srcdir)/Makefile.defines.in
{
SilcNetListener listener = (SilcNetListener)context;
- /* In case of error, the socket has been destroyed already */
+ /* In case of error, the socket has been destroyed already via
+ silc_stream_destroy. */
if (status != SILC_SOCKET_OK)
return;
/* Listen for connection */
void Listen()
{
+ SILC_LOG_DEBUG(("Listen()"));
+
new_conn = new RSocket;
if (!new_conn)
return;
/* Listener callback */
virtual void RunL()
{
+ SILC_LOG_DEBUG(("RunL(), iStatus=%d", iStatus));
+
if (iStatus != KErrNone) {
if (new_conn)
delete new_conn;
return;
}
+ SILC_LOG_DEBUG(("Accept new connection"));
+
/* Set socket options */
new_conn->SetOpt(KSoReuseAddr, KSolInetIp, 1);
SilcNetListener listener;
};
+extern "C" {
+
/* Create TCP listener */
SilcNetListener
if (local_ip_count > 0) {
listener->socks = (SilcSocket *)silc_calloc(local_ip_count,
- sizeof(*listener->socks));
+ sizeof(*listener->socks));
if (!listener->socks) {
callback(SILC_NET_NO_MEMORY, NULL, context);
return NULL;
/* Create the socket */
ret = l->sock.Open(l->ss, KAfInet, KSockStream, KProtocolInetTcp);
if (ret != KErrNone) {
- SILC_LOG_ERROR(("Cannot create socket"));
+ SILC_LOG_ERROR(("Cannot create socket, error %d", ret));
goto err;
}
/* Set the socket options */
ret = l->sock.SetOpt(KSoReuseAddr, KSolInetIp, 1);
if (ret != KErrNone) {
- SILC_LOG_ERROR(("Cannot set socket options"));
+ SILC_LOG_ERROR(("Cannot set socket options, error %d", ret));
goto err;
}
/* Bind the listener socket */
ret = l->sock.Bind(server);
if (ret != KErrNone) {
- SILC_LOG_DEBUG(("Cannot bind socket"));
+ SILC_LOG_DEBUG(("Cannot bind socket, error %d", ret));
goto err;
}
/* Specify that we are listenning */
ret = l->sock.Listen(5);
if (ret != KErrNone) {
- SILC_LOG_ERROR(("Cannot set socket listenning"));
+ SILC_LOG_ERROR(("Cannot set socket listenning, error %d", ret));
goto err;
}
l->Listen();
SILC_LOG_DEBUG(("Closing network listener"));
+ if (!listener)
+ return;
+
for (i = 0; i < listener->socks_count; i++) {
SilcSymbianTCPListener *l = (SilcSymbianTCPListener *)listener->socks[i];
l->sock.CancelAll();
silc_free(listener);
}
+} /* extern "C" */
+
/**************************** TCP/IP connecting *****************************/
static void silc_net_connect_stream(SilcSocketStreamStatus status,
- SilcStream stream, void *context);
+ SilcStream stream, void *context);
/* TCP connecting class */
/* Connect to remote host */
void Connect(TSockAddr &addr)
{
+ SILC_LOG_DEBUG(("Connect()"));
sock->Connect(addr, iStatus);
SetActive();
}
/* Connection callback */
virtual void RunL()
{
+ SILC_LOG_DEBUG(("RunL(), iStatus=%d", iStatus));
+
if (iStatus != KErrNone) {
if (callback)
callback(SILC_NET_ERROR, NULL, context);
return;
}
+ SILC_LOG_DEBUG(("Connected to host %s on %d", remote_ip, port));
+
/* Create stream */
if (callback) {
silc_socket_tcp_stream_create(
delete ss;
sock = NULL;
ss = NULL;
+ delete this;
}
-
- delete this;
}
/* Cancel */
void *context;
};
-/* Stream creation callback */
+extern "C" {
+
+/* TCP stream creation callback */
static void silc_net_connect_stream(SilcSocketStreamStatus status,
SilcStream stream, void *context)
SilcSymbianTCPConnect *conn = (SilcSymbianTCPConnect *)context;
SilcNetStatus net_status = SILC_NET_OK;
+ SILC_LOG_DEBUG(("Socket stream creation status %d", status));
+
if (status != SILC_SOCKET_OK) {
- /* In case of error, the socket has been destroyed already */
+ /* In case of error, the socket has been destroyed already via
+ silc_stream_destroy. */
if (status == SILC_SOCKET_UNKNOWN_IP)
net_status = SILC_NET_UNKNOWN_IP;
else if (status == SILC_SOCKET_UNKNOWN_HOST)
conn->callback = NULL;
conn->op = NULL;
if (conn->sock)
- sock->CancelConnect();
+ conn->sock->CancelConnect();
}
/* Create TCP/IP connection */
}
/* Do host lookup */
- if (!silc_net_is_ip(remote_ip_addr)) {
- if (!silc_net_gethostbyname(remote_ip_addr, FALSE, conn->remote_ip,
- sizeof(conn->remote_ip))) {
- SILC_LOG_ERROR(("Network (%s) unreachable: could not resolve the "
- "host", conn->remote));
- status = SILC_NET_HOST_UNREACHABLE;
- goto err;
- }
- } else {
- strcpy(conn->remote_ip, remote_ip_addr);
+ if (!silc_net_gethostbyname(remote_ip_addr, FALSE, conn->remote_ip,
+ sizeof(conn->remote_ip))) {
+ SILC_LOG_ERROR(("Network (%s) unreachable: could not resolve the "
+ "host", conn->remote));
+ status = SILC_NET_HOST_UNREACHABLE;
+ goto err;
}
/* Create the connection socket */
ret = conn->sock->Open(*conn->ss, KAfInet, KSockStream, KProtocolInetTcp);
if (ret != KErrNone) {
- SILC_LOG_ERROR(("Cannot create socket"));
+ SILC_LOG_ERROR(("Cannot create socket, error %d", ret));
status = SILC_NET_ERROR;
goto err;
}
tmp = (TText *)conn->remote_ip;
ret = remote.Input(tmp);
if (ret != KErrNone) {
- SILC_LOG_ERROR(("Cannot connect (cannot set address)"));
+ SILC_LOG_ERROR(("Cannot connect (cannot set address), error %d", ret));
status = SILC_NET_ERROR;
goto err;
}
SilcBool silc_net_addr2bin(const char *addr, void *bin, SilcUInt32 bin_len)
{
int ret = 0;
-
struct in_addr tmp;
+
ret = inet_aton(addr, &tmp);
if (bin_len < 4)
return FALSE;
s->sock->LocalName(addr);
return (SilcUInt16)addr.Port();
}
+
+} /* extern "C" */
\ No newline at end of file
\r
#include "silc.h"\r
\r
+extern "C" {\r
+\r
int silc_poll(SilcSchedule schedule, void *context)\r
{\r
/* Return immediately, timeout. */\r
/* Nothing to do */\r
}\r
\r
-const SilcScheduleOps schedule_ops =\r
+EXPORT_C const SilcScheduleOps schedule_ops =\r
{\r
silc_schedule_internal_init,\r
silc_schedule_internal_uninit,\r
silc_schedule_internal_signals_block,\r
silc_schedule_internal_signals_unblock,\r
};\r
+\r
+} /* extern "C" */
\ No newline at end of file
+
/*
silcsymbiansocketstream.cpp
/* Send data */
void Send(const TDesC8& buf, TSockXfrLength& ret_len)
{
+ SILC_LOG_DEBUG(("Send()"));
s->sock->Send(buf, 0, iStatus, ret_len);
SetActive();
}
TInetAddr remote;
TBuf<64> tmp;
+ SILC_LOG_DEBUG(("Send()"));
+
remote = TInetAddr(remote_port);
tmp = (TText *)remote_ip;
if (remote.Input(tmp) == KErrNone) {
/* Sending callback */
virtual void RunL()
{
+ SILC_LOG_DEBUG(("RunL(), iStatus=%d", iStatus));
+
if (iStatus != KErrNone) {
if (iStatus == KErrEof)
s->eof = 1;
}
/* 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 */
/* Read data */
void Read()
{
+ SILC_LOG_DEBUG(("Read()"));
+
if (!s->stream || s->stream->connected)
- s->sock->RecvOneOrMore(inbuf, 0, iStatus, inbuf_len);
+ s->sock->RecvOneOrMore(inbuf, 0, iStatus, read_len);
else
s->sock->RecvFrom(inbuf, remote, 0, iStatus);
+
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();
TBuf8<8192> inbuf;
const unsigned char *inbuf_ptr;
- TSockXfrLength inbuf_len;
+ TInt inbuf_len;
+ TSockXfrLength read_len;
SilcSymbianSocket *s;
TInetAddr remote;
};
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);
silc_free(stream);
return NULL;
}
+ 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,
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;
}
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;
}
if (ret_len() < data_len)
s->would_block = 1;
+ SILC_LOG_DEBUG(("Wrote %d bytes", ret_len()));
+
return ret_len();
}
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;
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);
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
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" */
/**************************** SILC Thread API *******************************/
+extern "C" {
+
/* Thread structure for Symbian */
typedef struct {
#ifdef SILC_THREADS
#ifdef SILC_THREADS
SilcSymbianThread tc = (SilcSymbianThread)context;
SilcThreadStart start_func = tc->start_func;
- void *context = tc->context;
+ void *user_context = tc->context;
SilcBool waitable = tc->waitable;
silc_free(tc);
/* Call the thread function */
if (waitable)
- silc_thread_exit(start_func(context));
+ silc_thread_exit(start_func(user_context));
else
- start_func(context);
+ start_func(user_context);
#endif
return KErrNone;
/* Executed new thread */
SilcThread silc_thread_create(SilcThreadStart start_func, void *context,
- bool waitable)
+ SilcBool waitable)
{
#ifdef SILC_THREADS
SilcSymbianThread tc;
void silc_thread_exit(void *exit_value)
{
#ifdef SILC_THREADS
- RThread().Kill((Tint)exit_value);
+ RThread().Kill((TInt)exit_value);
#endif
}
SilcThread silc_thread_self(void)
{
#ifdef SILC_THREADS
- return (SilcThread)&RThread();
+ RThread thread = RThread();
+ return (SilcThread)&thread;
#else
return NULL;
#endif
void silc_rwlock_free(SilcRwLock rwlock)
{
#ifdef SILC_THREADS
- if (mutex) {
+ if (rwlock) {
silc_mutex_free(rwlock->mutex);
silc_cond_free(rwlock->cond);
silc_free(rwlock);
return FALSE;
#endif /* SILC_THREADS*/
}
+
+} /* extern "C" */
\ No newline at end of file
-/*\r
-\r
- silcsymbianutil.cpp\r
-\r
- Author: Pekka Riikonen <priikone@silcnet.org>\r
-\r
- Copyright (C) 2006 Pekka Riikonen\r
-\r
- This program is free software; you can redistribute it and/or modify\r
- it under the terms of the GNU General Public License as published by\r
- the Free Software Foundation; version 2 of the License.\r
-\r
- This program is distributed in the hope that it will be useful,\r
- but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- GNU General Public License for more details.\r
-\r
-*/\r
-\r
-#include "silc.h"\r
-\r
-/* Returns the username of the user. */\r
-\r
-char *silc_get_username()\r
-{\r
- char *logname = NULL;\r
-\r
- logname = getlogin();\r
- if (!logname) {\r
- struct passwd *pw;\r
-\r
- pw = getpwuid(getuid());\r
- if (!pw)\r
- return strdup("User");\r
-\r
- logname = pw->pw_name;\r
- }\r
-\r
- return strdup(logname);\r
-}\r
-\r
-/* Returns the real name of ther user. */\r
-\r
-char *silc_get_real_name()\r
-{\r
- char *realname = NULL;\r
- struct passwd *pw;\r
-\r
- pw = getpwuid(getuid());\r
- if (!pw)\r
- return strdup("No Name");\r
-\r
- if (strchr(pw->pw_gecos, ','))\r
- *strchr(pw->pw_gecos, ',') = 0;\r
-\r
- if (!strlen(pw->pw_gecos))\r
- return strdup("No Name");\r
-\r
- realname = strdup(pw->pw_gecos);\r
-\r
- return realname;\r
-}\r
-\r
-/* Return current time to struct timeval. */\r
-\r
-int silc_gettimeofday(struct timeval *p)\r
-{\r
- return gettimeofday(p, NULL);\r
-}\r
-\r
-int silc_file_set_nonblock(int fd)\r
-{\r
- return 0;\r
-}\r
+/*
+
+ silcsymbianutil.cpp
+
+ Author: Pekka Riikonen <priikone@silcnet.org>
+
+ Copyright (C) 2006 Pekka Riikonen
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+*/
+
+#include "silc.h"
+#include <e32std.h>
+#include <e32svr.h>
+
+extern "C" {
+
+/* Returns the username of the user. */
+
+char *silc_get_username()
+{
+ char *logname = NULL;
+
+ logname = getlogin();
+ if (!logname) {
+ struct passwd *pw;
+
+ pw = getpwuid(getuid());
+ if (!pw)
+ return strdup("User");
+
+ logname = pw->pw_name;
+ }
+
+ return strdup(logname);
+}
+
+/* Returns the real name of ther user. */
+
+char *silc_get_real_name()
+{
+ char *realname = NULL;
+ struct passwd *pw;
+
+ pw = getpwuid(getuid());
+ if (!pw)
+ return strdup("No Name");
+
+ if (strchr(pw->pw_gecos, ','))
+ *strchr(pw->pw_gecos, ',') = 0;
+
+ if (!strlen(pw->pw_gecos))
+ return strdup("No Name");
+
+ realname = strdup(pw->pw_gecos);
+
+ return realname;
+}
+
+/* Return current time to struct timeval. */
+
+int silc_gettimeofday(struct timeval *p)
+{
+ return gettimeofday(p, NULL);
+}
+
+int silc_file_set_nonblock(int fd)
+{
+ return 0;
+}
+
+void silc_symbian_usleep(long microseconds)
+{
+ User::After(microseconds / 1000);
+}
+
+void silc_symbian_debug(const char *function, int line, char *string)
+{
+ RDebug::Print(_L("%s:%d: %s"), function, line, string);
+}
+
+} /* extern "C" */