[Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/ptII/ptinyos/tos/platform/ptII
external_comm.c, 1.4, 1.5 external_comm.h, 1.2, 1.3 ptII.c, 1.6, 1.7
Elaine Cheong
celaine at users.sourceforge.net
Thu Jun 29 16:11:56 PDT 2006
Update of /cvsroot/tinyos/tinyos-1.x/contrib/ptII/ptinyos/tos/platform/ptII
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv8317/tos/platform/ptII
Modified Files:
external_comm.c external_comm.h ptII.c
Log Message:
Replaced C socket operations with Java socket operations for event thread only.
Index: external_comm.c
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/contrib/ptII/ptinyos/tos/platform/ptII/external_comm.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** external_comm.c 1 Feb 2006 07:50:12 -0000 1.4
--- external_comm.c 29 Jun 2006 23:11:54 -0000 1.5
***************
*** 85,91 ****
int commandClients[MAX_CLIENT_CONNECTIONS];
uint8_t batchState[MAX_CLIENT_CONNECTIONS];
! norace int eventClients[MAX_CLIENT_CONNECTIONS];
norace uint16_t eventMask;
// Viptos: functions to create, enter, exit, wait, and broadcast
// (notifyAll()) on monitor.
--- 85,112 ----
int commandClients[MAX_CLIENT_CONNECTIONS];
uint8_t batchState[MAX_CLIENT_CONNECTIONS];
! // Viptos: replacing C socket operations with Java sockets.
! //norace int eventClients[MAX_CLIENT_CONNECTIONS];
! norace void* eventClients[MAX_CLIENT_CONNECTIONS]; // array of SocketChannel
norace uint16_t eventMask;
+ #define __PTII_SOCKET__ 1
+ #if defined(__PTII_SOCKET__)
+ // Viptos: replacing C socket operations with Java sockets.
+ extern void* ptII_serverSocketCreate(short port);
+ extern void ptII_serverSocketClose(void *serverSocket);
+ extern void* ptII_selectorCreate(void *serverSocket);
+ extern void ptII_selectorClose(void *selector);
+ extern void* ptII_selectSocket(void *selector, char *selectorIsClosing);
+ extern void* ptII_acceptConnection(void *serverSocketChannel);
+ extern void ptII_socketChannelClose(void *socketChannel);
+ extern int ptII_socketChannelWrite(void *socketChannel, void *data, int datalen);
+ extern int ptII_socketChannelRead(void *socketChannel, void *data, int datalen);
+
+ int ptIIcount = 0;
+ void* ptIIServerSocket1; // commandServer
+ void* ptIIServerSocket2; // eventServer
+ void *selector; // eventAccept
+ #endif//if defined(__PTII_SOCKET__)
+
// Viptos: functions to create, enter, exit, wait, and broadcast
// (notifyAll()) on monitor.
***************
*** 147,151 ****
for (i = 0; i < MAX_CLIENT_CONNECTIONS; i++) {
commandClients[i] = -1;
! eventClients[i] = -1;
batchState[i] = 0;
}
--- 168,174 ----
for (i = 0; i < MAX_CLIENT_CONNECTIONS; i++) {
commandClients[i] = -1;
! // Viptos: replacing C socket operations with Java sockets.
! //eventClients[i] = -1;
! eventClients[i] = NULL;
batchState[i] = 0;
}
***************
*** 171,174 ****
--- 194,221 ----
***************************************************************************/
+ void* acceptConnection2(void *serverSocketChannel) {
+ // Viptos: replacing C socket operations with Java sockets.
+ //struct sockaddr_in cli_addr;
+ //int clilen = sizeof(cli_addr);
+ //int clifd;
+ void *socketChannel;
+
+ EC_DEBUG(dbg_clear(DBG_SIM, "SIM: Waiting for connection on serverSocketChannel %p\n", serverSocketChannel));
+ //clifd = accept(servfd, (struct sockaddr*)&cli_addr, &clilen);
+ socketChannel = ptII_acceptConnection(serverSocketChannel);
+ //if (clifd < 0) {
+ if (socketChannel == NULL) {
+ //EC_DEBUG(dbg_clear(DBG_SIM, "SIM: Could not accept socket: %s\n", strerror(errno)));
+ EC_DEBUG(dbg_clear(DBG_SIM, "SIM: Could not accept socket.\n"));
+ // MDW: Maybe want to return -1 and keep going
+ //exit(-1);
+ // celaine
+ //return -1;
+ return NULL;
+ }
+ EC_DEBUG(dbg_clear(DBG_SIM, "SIM: Accepted client socket: fd %p\n", socketChannel));
+ return socketChannel;
+ }
+
int acceptConnection(int servfd) {
struct sockaddr_in cli_addr;
***************
*** 176,179 ****
--- 223,229 ----
int clifd;
+ // Viptos: replacing C socket operations with Java sockets.
+ // return acceptConnection(slectionKey)
+
EC_DEBUG(dbg_clear(DBG_SIM, "SIM: Waiting for connection on socket %d\n", servfd));
clifd = accept(servfd, (struct sockaddr*)&cli_addr, &clilen);
***************
*** 194,197 ****
--- 244,250 ----
int rval = -1;
long enable = 1;
+
+ // Viptos: replacing C socket operations with Java sockets.
+ if (ptIIcount == 0) {
memset(&sock, 0, sizeof(sock));
***************
*** 222,225 ****
--- 275,285 ----
}
dbg_clear(DBG_SIM, "SIM: Created server socket listening on port %d.\n", port);
+
+ // Viptos: replacing C socket operations with Java sockets.
+ } else {
+ ptIIServerSocket2 = ptII_serverSocketCreate(port);
+ }
+ ptIIcount++;
+
return sfd;
}
***************
*** 227,242 ****
// celaine
void shutdownSockets() __attribute__ ((C, spontaneous)) {
socketsInitialized = 0;
if (shutdown(commandServerSocket, SHUT_RDWR) < 0) {
dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Could not shutdown command server socket: %s\n", strerror(errno));
} else {
dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Shut down command server socket.\n");
}
if (shutdown(eventServerSocket, SHUT_RDWR) < 0) {
dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Could not shutdown event server socket: %s\n", strerror(errno));
} else {
dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Shut down event server socket.\n");
}
!
if (ptII_joinThreads() == 0) {
dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Joined commandReadThread.\n");
--- 287,329 ----
// celaine
void shutdownSockets() __attribute__ ((C, spontaneous)) {
+
+
+
socketsInitialized = 0;
+
if (shutdown(commandServerSocket, SHUT_RDWR) < 0) {
+ //if (close(commandServerSocket) < 0) {
dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Could not shutdown command server socket: %s\n", strerror(errno));
+ //dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Could not close command server socket: %s\n", strerror(errno));
} else {
dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Shut down command server socket.\n");
+ //dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Closed command server socket.\n");
}
+
+
+ ptII_selectorClose(selector);
+ dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Shut down event server selector.\n");
+ ptII_serverSocketClose(ptIIServerSocket2);
+ dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Shut down event server socket.\n");
+
+ /*
+ dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Begin to shut down event server socket.\n");
+
+ ptII_serverSocketClose(ptIIServerSocket2);
+ dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Shut down event server socket.\n");
+ //ptII_selectorClose(selector);
+ //dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Shut down event server selector.\n");
+ */
+
+ /*
if (shutdown(eventServerSocket, SHUT_RDWR) < 0) {
+ //if (close(eventServerSocket) < 0) {
dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Could not shutdown event server socket: %s\n", strerror(errno));
+ //dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Could not close event server socket: %s\n", strerror(errno));
} else {
dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Shut down event server socket.\n");
+ //dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Closed event server socket.\n");
}
! */
if (ptII_joinThreads() == 0) {
dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Joined commandReadThread.\n");
***************
*** 245,248 ****
--- 332,337 ----
dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Could not join commandReadThread or eventAcceptThread.\n");
}
+
+
/*
if (pthread_join(commandReadThread, NULL) != 0) {
***************
*** 292,299 ****
while (numclients == 0) {
for (n = 0; n < MAX_CLIENT_CONNECTIONS; n++) {
! if (eventClients[n] != -1) {
! dbg_clear(DBG_SIM, "SIM: Got client connection fd %d\n", eventClients[n]);
! numclients++;
! }
}
if (numclients == 0) {
--- 381,391 ----
while (numclients == 0) {
for (n = 0; n < MAX_CLIENT_CONNECTIONS; n++) {
! // Viptos: replacing C socket operations with Java sockets.
! if (eventClients[n] != NULL) {
! //if (eventClients[n] != -1) {
! //dbg_clear(DBG_SIM, "SIM: Got client connection fd %d\n", eventClients[n]);
! dbg_clear(DBG_SIM, "SIM: Got client connection fd %p\n", eventClients[n]);
! numclients++;
! }
}
if (numclients == 0) {
***************
*** 334,337 ****
--- 426,445 ----
}
+ // Viptos: replacing C socket operations with Java sockets.
+ void addClient2(void *clientSockets[], void* socketChannel) {
+ int i;
+
+ for (i = 0; i < MAX_CLIENT_CONNECTIONS; i++) {
+ if (clientSockets[i] == NULL) {
+ clientSockets[i] = socketChannel;
+ return;
+ }
+ }
+
+ // client state is full - drop connection
+ //close(clifd);
+ ptII_socketChannelClose(socketChannel);
+ }
+
void addClient(int *clientSockets, int clifd) {
int i;
***************
*** 348,351 ****
--- 456,476 ----
}
+ // Viptos: replacing C socket operations with Java sockets.
+ void sendInitEvent2(void* socketChannel) {
+ //void sendInitEvent(int clifd) {
+ TossimInitEvent initEv;
+ unsigned char* msg;
+ int total_size;
+
+ memset((char*)&initEv, 0, sizeof(TossimInitEvent));
+ initEv.numMotes = tos_state.num_nodes;
+ initEv.radioModel = tos_state.radioModel;
+ initEv.rate = get_sim_rate();
+ buildTossimEvent(0, AM_TOSSIMINITEVENT,
+ tos_state.tos_time, &initEv, &msg, &total_size);
+ writeTossimEvent2(msg, total_size, socketChannel);
+ free(msg);
+ }
+
void sendInitEvent(int clifd) {
TossimInitEvent initEv;
***************
*** 368,408 ****
void *eventAcceptThreadFunc(void *arg) __attribute__ ((C, spontaneous)) {
! int clifd;
! fd_set acceptset;
dbg_clear(DBG_SIM, "SIM: eventAcceptThread running.\n");
while (1) {
! FD_ZERO(&acceptset);
! FD_SET(eventServerSocket, &acceptset);
! EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: calling select\n"));
! if (select(eventServerSocket + 1, &acceptset, NULL, NULL, NULL) < 0) {
! EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThreadFunc: error in select(): %s\n", strerror(errno)));
! }
! EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: select returned\n"));
! if (FD_ISSET(eventServerSocket, &acceptset)) {
! EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: Checking for event connection\n"));
! clifd = acceptConnection(eventServerSocket);
! // celaine
! if (clifd < 0) {
! EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: acceptConnection failed\n"));
! return 0;
}
! EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: Got event connection %d\n", clifd));
! // Viptos: Replacing pthread objects with JNI objects.
! ptII_MonitorEnter(eventClientsLock);
! //pthread_mutex_lock(&eventClientsLock);
! addClient(eventClients, clifd);
! sendInitEvent(clifd);
! //pthread_cond_broadcast(&eventClientsCond);
! ptII_MonitorNotifyAll(eventClientsLock);
! //pthread_mutex_unlock(&eventClientsLock);
! ptII_MonitorExit(eventClientsLock);
! }
}
return 0;
--- 493,562 ----
void *eventAcceptThreadFunc(void *arg) __attribute__ ((C, spontaneous)) {
! // Viptos: replacing C socket operations with Java sockets.
! //int clifd;
! //fd_set acceptset;
+ // Viptos: replacing C socket operations with Java sockets.
+
+ void *serverSocketChannel;
+ void *socketChannel;
+ char selectorIsClosing = 0;
+
dbg_clear(DBG_SIM, "SIM: eventAcceptThread running.\n");
+ // Viptos: replacing C socket operations with Java sockets.
+ selector = ptII_selectorCreate(ptIIServerSocket2);
+
while (1) {
! // Viptos: replacing C socket operations with Java sockets.
! //FD_ZERO(&acceptset);
! //FD_SET(eventServerSocket, &acceptset);
! EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: calling select\n"));
! //if (select(eventServerSocket + 1, &acceptset, NULL, NULL, NULL) < 0) {
! // Call to ptII_selectSocket() is a blocking call.
! serverSocketChannel = ptII_selectSocket(selector, &selectorIsClosing);
! EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: returned from select\n"));
! if (serverSocketChannel == NULL) {
! if (selectorIsClosing) {
! EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThreadFunc: selector is closing.\n"));
! return 0;
! } else {
! EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThreadFunc: error in select(): %s\n", strerror(errno)));
! return 0;
! }
}
! EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: select returned\n"));
! //if (FD_ISSET(eventServerSocket, &acceptset)) {
! if (serverSocketChannel != NULL) {
! EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: Checking for event connection\n"));
! //clifd = acceptConnection(eventServerSocket);
! socketChannel = acceptConnection2(serverSocketChannel);
! EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: Returned from acceptConnection2\n"));
! //// celaine
! //if (clifd < 0) {
! if (socketChannel == NULL) {
! EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: acceptConnection failed\n"));
! return 0;
! }
! //EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: Got event connection %d\n", clifd));
! EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: Got event connection %p\n", socketChannel));
!
! //// Viptos: Replacing pthread objects with JNI objects.
! ptII_MonitorEnter(eventClientsLock);
! ////pthread_mutex_lock(&eventClientsLock);
! //addClient(eventClients, clifd);
! addClient2(eventClients, socketChannel);
! //sendInitEvent(clifd);
! sendInitEvent2(socketChannel);
! ////pthread_cond_broadcast(&eventClientsCond);
! ptII_MonitorNotifyAll(eventClientsLock);
! ////pthread_mutex_unlock(&eventClientsLock);
! ptII_MonitorExit(eventClientsLock);
! }
}
return 0;
***************
*** 832,835 ****
--- 986,1036 ----
***************************************************************************/
+ // Viptos: replacing C socket operations with Java sockets.
+ // Write an event to the given client socket and wait for an ACK.
+ // Returns 0 if successful, -1 if the client connection was closed
+ int writeTossimEvent2(void *data, int datalen, void* socketChannel) {
+ unsigned char ack;
+ int i, j;
+
+ /* Debugging only */
+ /* fprintf(stderr,"WRITING: ");
+ * for (i = 0; i < datalen; i++) {
+ * fprintf(stderr,"%2x ", ((unsigned char *)data)[i]);
+ * }
+ * fprintf(stderr,"\n");
+ */
+
+ //EC_DEBUG(fprintf(stderr, "writeTossimEvent: fd %d datalen %d (0x%2x)\n", clifd, datalen, datalen));
+ EC_DEBUG(fprintf(stderr, "writeTossimEvent: socketChannel %p datalen %d (0x%2x)\n", socketChannel, datalen, datalen));
+ j = 0;
+ // XXX PAL: Is there a chance that we don't write everything
+ // and need to loop? Hope and pray, I guess...
+
+ // Viptos: replacing C socket operations with Java sockets.
+ //i = send(clifd, data, datalen, 0);
+ i = ptII_socketChannelWrite(socketChannel, data, datalen);
+
+ EC_DEBUG(fprintf(stderr, "writeTossimEvent: waiting for ack...\n"));
+ // Viptos: replacing C socket operations with Java sockets.
+ //if (i >= 0) j = read(clifd, &ack, 1);
+ if (i >= 0) {
+ j = ptII_socketChannelRead(socketChannel, &ack, 1);
+ }
+
+ EC_DEBUG(fprintf(stderr, "writeTossimEvent: ack received...\n"));
+ if ((i < 0) || (j < 0)) {
+ EC_DEBUG(fprintf(stderr, "writeTossimEvent: Socket closed: %s\n", strerror(errno)));
+ //close(clifd);
+ ptII_socketChannelClose(socketChannel);
+
+ return -1;
+ // XXX MDW: If -gui, should really wait for a new connection?
+ // That's painful if we have multiple clients...
+ }
+ EC_DEBUG(fprintf(stderr, "writeTossimEvent: done\n"));
+ return 0;
+ }
+
+
// Write an event to the given client socket and wait for an ACK.
// Returns 0 if successful, -1 if the client connection was closed
***************
*** 930,934 ****
int n;
int numclients = 0;
! int clients[MAX_CLIENT_CONNECTIONS];
if (!socketsInitialized) return;
--- 1131,1137 ----
int n;
int numclients = 0;
! // Viptos: replacing C socket operations with Java sockets.
! //int clients[MAX_CLIENT_CONNECTIONS];
! void* clients[MAX_CLIENT_CONNECTIONS];
if (!socketsInitialized) return;
***************
*** 940,945 ****
while (numclients == 0) {
for (n = 0; n < MAX_CLIENT_CONNECTIONS; n++) {
! clients[n] = -1;
! if (eventClients[n] != -1) {
clients[n] = eventClients[n];
numclients++;
--- 1143,1150 ----
while (numclients == 0) {
for (n = 0; n < MAX_CLIENT_CONNECTIONS; n++) {
! //clients[n] = -1;
! clients[n] = NULL;
! //if (eventClients[n] != -1) {
! if (eventClients[n] != NULL) {
clients[n] = eventClients[n];
numclients++;
***************
*** 973,990 ****
for (n = 0; n < MAX_CLIENT_CONNECTIONS; n++) {
! if (clients[n] != -1 && ((type & eventMask) != 0)) {
! if (writeTossimEvent(msg, total_size, clients[n]) < 0) {
! // Socket closed
! // Viptos: Replacing pthread objects with JNI objects.
! ptII_MonitorEnter(eventClientsLock);
! //pthread_mutex_lock(&eventClientsLock);
! eventClients[n] = -1;
! //pthread_mutex_unlock(&eventClientsLock);
! ptII_MonitorExit(eventClientsLock);
}
- }
}
EC_DEBUG(fprintf(stderr, "Sent.\n"));
--- 1178,1198 ----
for (n = 0; n < MAX_CLIENT_CONNECTIONS; n++) {
! //if (clients[n] != -1 && ((type & eventMask) != 0)) {
! if (clients[n] != NULL && ((type & eventMask) != 0)) {
! //if (writeTossimEvent(msg, total_size, clients[n]) < 0) {
! if (writeTossimEvent2(msg, total_size, clients[n]) < 0) {
! // Socket closed
! // Viptos: Replacing pthread objects with JNI objects.
! ptII_MonitorEnter(eventClientsLock);
! //pthread_mutex_lock(&eventClientsLock);
! //eventClients[n] = -1;
! eventClients[n] = NULL;
! //pthread_mutex_unlock(&eventClientsLock);
! ptII_MonitorExit(eventClientsLock);
! }
}
}
EC_DEBUG(fprintf(stderr, "Sent.\n"));
Index: external_comm.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/contrib/ptII/ptinyos/tos/platform/ptII/external_comm.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** external_comm.h 17 Jan 2006 04:12:43 -0000 1.2
--- external_comm.h 29 Jun 2006 23:11:54 -0000 1.3
***************
*** 53,56 ****
--- 53,59 ----
int writeTossimEvent(void *data, int datalen, int clifd);
+ // Viptos: replacing C socket operations with Java sockets.
+ int writeTossimEvent2(void *data, int datalen, void* socketChannel);
+
int notifyTaskPosted(char* task);
int notifyEventSignaled(char* event);
Index: ptII.c
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/contrib/ptII/ptinyos/tos/platform/ptII/ptII.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** ptII.c 1 Feb 2006 07:50:12 -0000 1.6
--- ptII.c 29 Jun 2006 23:11:54 -0000 1.7
***************
*** 87,90 ****
--- 87,100 ----
jmethodID ptII_jmethodID_startThreads;
+ jmethodID ptII_jmethodID_serverSocketCreate;
+ jmethodID ptII_jmethodID_serverSocketClose;
+ jmethodID ptII_jmethodID_selectorCreate;
+ jmethodID ptII_jmethodID_selectorClose;
+ jmethodID ptII_jmethodID_selectSocket;
+ jmethodID ptII_jmethodID_acceptConnection;
+ jmethodID ptII_jmethodID_socketChannelClose;
+ jmethodID ptII_jmethodID_socketChannelWrite;
+ jmethodID ptII_jmethodID_socketChannelRead;
+
// Methods in the Object class in Java.
jmethodID ptII_jmethodID_Object_notify;
***************
*** 188,191 ****
--- 198,277 ----
}
+ /////////////////////// Begin socket methods //////////////////////////
+
+ // Store handle to serverSocketCreate() method in Java.
+ ptII_jmethodID_serverSocketCreate = (*env)->GetMethodID(env, cls, "serverSocketCreate", "(S)Ljava/net/ServerSocket;");
+ if (ptII_jmethodID_serverSocketCreate == 0) {
+ // FIXME throw exception
+ fprintf(stderr, "Could not find method: void serverSocketCreate()\n");
+ return -1;
+ }
+
+ // Store handle to serverSocketClose() method in Java.
+ ptII_jmethodID_serverSocketClose = (*env)->GetMethodID(env, cls, "serverSocketClose", "(Ljava/net/ServerSocket;)V");
+ if (ptII_jmethodID_serverSocketClose == 0) {
+ // FIXME throw exception
+ fprintf(stderr, "Could not find method: void serverSocketClose()\n");
+ return -1;
+ }
+
+ // Store handle to selectorCreate() method in Java.
+ ptII_jmethodID_selectorCreate = (*env)->GetMethodID(env, cls, "selectorCreate", "(Ljava/net/ServerSocket;)Ljava/nio/channels/Selector;");
+ if (ptII_jmethodID_selectorCreate == 0) {
+ // FIXME throw exception
+ fprintf(stderr, "Could not find method: void selectorCreate()\n");
+ return -1;
+ }
+
+ // Store handle to selectorClose() method in Java.
+ ptII_jmethodID_selectorClose = (*env)->GetMethodID(env, cls, "selectorClose", "(Ljava/nio/channels/Selector;)V");
+ if (ptII_jmethodID_selectorClose == 0) {
+ // FIXME throw exception
+ fprintf(stderr, "Could not find method: void selectorClose()\n");
+ return -1;
+ }
+
+ // Store handle to selectSocket() method in Java.
+ ptII_jmethodID_selectSocket = (*env)->GetMethodID(env, cls, "selectSocket", "(Ljava/nio/channels/Selector;[Z)Ljava/nio/channels/ServerSocketChannel;");
+ if (ptII_jmethodID_selectSocket == 0) {
+ // FIXME throw exception
+ fprintf(stderr, "Could not find method: void selectSocket()\n");
+ return -1;
+ }
+
+ // Store handle to acceptConnection() method in Java.
+ ptII_jmethodID_acceptConnection = (*env)->GetMethodID(env, cls, "acceptConnection", "(Ljava/nio/channels/ServerSocketChannel;)Ljava/nio/channels/SocketChannel;");
+ if (ptII_jmethodID_acceptConnection == 0) {
+ // FIXME throw exception
+ fprintf(stderr, "Could not find method: void acceptConnection()\n");
+ return -1;
+ }
+
+ // Store handle to socketChannelClose() method in Java.
+ ptII_jmethodID_socketChannelClose = (*env)->GetMethodID(env, cls, "socketChannelClose", "(Ljava/nio/channels/SocketChannel;)V");
+ if (ptII_jmethodID_socketChannelClose == 0) {
+ // FIXME throw exception
+ fprintf(stderr, "Could not find method: void socketChannelClose()\n");
+ return -1;
+ }
+
+ // Store handle to socketChannelWrite() method in Java.
+ ptII_jmethodID_socketChannelWrite = (*env)->GetMethodID(env, cls, "socketChannelWrite", "(Ljava/nio/channels/SocketChannel;[B)I");
+ if (ptII_jmethodID_socketChannelWrite == 0) {
+ // FIXME throw exception
+ fprintf(stderr, "Could not find method: void socketChannelWrite()\n");
+ return -1;
+ }
+
+ // Store handle to socketChannelRead() method in Java.
+ ptII_jmethodID_socketChannelRead = (*env)->GetMethodID(env, cls, "socketChannelRead", "(Ljava/nio/channels/SocketChannel;[B)I");
+ if (ptII_jmethodID_socketChannelRead == 0) {
+ // FIXME throw exception
+ fprintf(stderr, "Could not find method: void socketChannelRead()\n");
+ return -1;
+ }
+
+ /////////////////////// End socket methods ////////////////////////////
+
// --------------------------------------------------------------------
// Reference to the Object class in Java.
***************
*** 476,479 ****
--- 562,810 ----
}
+ /////////////////////// Begin socket methods //////////////////////////
+
+ // Create socket.
+ // Returns object of type ServerSocket
+ void* ptII_serverSocketCreate(short port) {
+ JNIEnv *env = NULL;
+ jobject obj = ptII_global_obj;
+
+ // Attach the current thread to the JVM if it has not already been
+ // attached and get the environment.
+ if ((*ptII_vm)->AttachCurrentThread(ptII_vm, (void **) &env, NULL) < 0) {
+ fprintf(stderr, "Error in %s[%d]: AttachCurrentThread ()\n",
+ __FILE__, __LINE__);
+ return NULL;
+ }
+
+ // Call serverSocketCreate() in Java
+ jobject serverSocket = (*env)->CallObjectMethod(env, obj, ptII_jmethodID_serverSocketCreate, port);
+
+ // Create a global reference so that we can save the reference to
+ // the lock object over multiple calls.
+ if ((serverSocket = (*env)->NewGlobalRef(env, serverSocket)) == NULL) {
+ fprintf(stderr, "Error in %s[%d]: NewGlobalRef ()\n",
+ __FILE__, __LINE__);
+ return NULL;
+ }
+
+ return serverSocket;
+ }
+
+ // Close the ServerSocket
+ void ptII_serverSocketClose(void *serverSocket) {
+ jobject obj = ptII_global_obj;
+
+ JNIEnv *env;
+ // Attach the current thread to the JVM if it has not already been
+ // attached and get the environment.
+ if ((*ptII_vm)->AttachCurrentThread(ptII_vm, (void **) &env, NULL) < 0) {
+ fprintf(stderr, "Error in %s[%d]: AttachCurrentThread ()\n",
+ __FILE__, __LINE__);
+ return;
+ }
+
+ // Call serverSocketClose() in Java
+ (*env)->CallVoidMethod(env, obj, ptII_jmethodID_serverSocketClose, (jobject)serverSocket);
+ }
+
+ // Create Selector object and register the ServerSocket with the selector.
+ // Returns object of type Selector
+ void* ptII_selectorCreate(void *serverSocket) {
+ jobject obj = ptII_global_obj;
+
+ JNIEnv *env;
+ // Attach the current thread to the JVM if it has not already been
+ // attached and get the environment.
+ if ((*ptII_vm)->AttachCurrentThread(ptII_vm, (void **) &env, NULL) < 0) {
+ fprintf(stderr, "Error in %s[%d]: AttachCurrentThread ()\n",
+ __FILE__, __LINE__);
+ return NULL;
+ }
+
+ // Call selectorCreate() in Java
+ jobject selector = (*env)->CallObjectMethod(env, obj, ptII_jmethodID_selectorCreate, (jobject)serverSocket);
+
+ // Create a global reference so that we can save the reference to
+ // the lock object over multiple calls.
+ if ((selector = (*env)->NewGlobalRef(env, selector)) == NULL) {
+ fprintf(stderr, "Error in %s[%d]: NewGlobalRef ()\n",
+ __FILE__, __LINE__);
+ return NULL;
+ }
+
+ return selector;
+ }
+
+ // Close the Selector
+ void ptII_selectorClose(void *selector) {
+ jobject obj = ptII_global_obj;
+
+ JNIEnv *env;
+ // Attach the current thread to the JVM if it has not already been
+ // attached and get the environment.
+ if ((*ptII_vm)->AttachCurrentThread(ptII_vm, (void **) &env, NULL) < 0) {
+ fprintf(stderr, "Error in %s[%d]: AttachCurrentThread ()\n",
+ __FILE__, __LINE__);
+ return;
+ }
+
+ // Call selectorClose() in Java
+ (*env)->CallVoidMethod(env, obj, ptII_jmethodID_selectorClose, (jobject)selector);
+ }
+
+ // Call select().
+ // selectorIsClosing gets set to true (value = 1) if the selector is about to close.
+ // See external_comm.c: eventAcceptThreadFunc()
+ // Also see $PTII/ptolemy/domains/ptinyos/kernel/PtinyOSDirector.java: selectorClose()
+
+ // Returns object of type ServerSocketChannel.
+ void* ptII_selectSocket(void *selector, char *selectorIsClosing) {
+ jobject obj = ptII_global_obj;
+
+ JNIEnv *env;
+ // Attach the current thread to the JVM if it has not already been
+ // attached and get the environment.
+ if ((*ptII_vm)->AttachCurrentThread(ptII_vm, (void **) &env, NULL) < 0) {
+ fprintf(stderr, "Error in %s[%d]: AttachCurrentThread ()\n",
+ __FILE__, __LINE__);
+ return NULL;
+ }
+
+ jbooleanArray booleanArray;
+ booleanArray = (*env)->NewBooleanArray(env, 1);
+
+ // Call selectSocket() in Java
+ jobject serverSocketChannel = (*env)->CallObjectMethod(env, obj, ptII_jmethodID_selectSocket, (jobject)selector, booleanArray);
+
+ jboolean *dataRead = (*env)->GetBooleanArrayElements(env, booleanArray, NULL);
+
+ *selectorIsClosing = dataRead[0];
+
+ // Create a global reference so that we can save the reference to
+ // the serverSocketChannel object over multiple calls.
+ if ((serverSocketChannel = (*env)->NewGlobalRef(env, serverSocketChannel)) == NULL) {
+
+ // Selector is about to close.
+ if (*selectorIsClosing) {
+ return NULL;
+ }
+
+ fprintf(stderr, "Error in %s[%d]: NewGlobalRef ()\n",
+ __FILE__, __LINE__);
+ return NULL;
+ }
+
+ return serverSocketChannel;
+ }
+
+ // Accept the connection.
+ // Returns object of type ServerSocketChannel.
+ void* ptII_acceptConnection(void *serverSocketChannel) {
+ jobject obj = ptII_global_obj;
+
+ JNIEnv *env;
+ // Attach the current thread to the JVM if it has not already been
+ // attached and get the environment.
+ if ((*ptII_vm)->AttachCurrentThread(ptII_vm, (void **) &env, NULL) < 0) {
+ fprintf(stderr, "Error in %s[%d]: AttachCurrentThread ()\n",
+ __FILE__, __LINE__);
+ return NULL;
+ }
+
+ // Call acceptConnection() in Java
+ jobject socketChannel = (*env)->CallObjectMethod(env, obj, ptII_jmethodID_acceptConnection, (jobject)serverSocketChannel);
+
+ // Create a global reference so that we can save the reference to
+ // the lock object over multiple calls.
+ if ((socketChannel = (*env)->NewGlobalRef(env, socketChannel)) == NULL) {
+ fprintf(stderr, "Error in %s[%d]: NewGlobalRef ()\n",
+ __FILE__, __LINE__);
+ return NULL;
+ }
+
+ return socketChannel;
+ }
+
+ // Close the SocketChannel
+ void ptII_socketChannelClose(void *socketChannel) {
+ jobject obj = ptII_global_obj;
+
+ JNIEnv *env;
+ // Attach the current thread to the JVM if it has not already been
+ // attached and get the environment.
+ if ((*ptII_vm)->AttachCurrentThread(ptII_vm, (void **) &env, NULL) < 0) {
+ fprintf(stderr, "Error in %s[%d]: AttachCurrentThread ()\n",
+ __FILE__, __LINE__);
+ return;
+ }
+
+ // Call socketChannelClose() in Java
+ (*env)->CallVoidMethod(env, obj, ptII_jmethodID_socketChannelClose, (jobject)socketChannel);
+ }
+
+ // Write to socket.
+ // Returns number of bytes written. -1 if error.
+ int ptII_socketChannelWrite(void *socketChannel, void *data, int datalen) {
+ jobject obj = ptII_global_obj;
+
+ JNIEnv *env;
+ // Attach the current thread to the JVM if it has not already been
+ // attached and get the environment.
+ if ((*ptII_vm)->AttachCurrentThread(ptII_vm, (void **) &env, NULL) < 0) {
+ fprintf(stderr, "Error in %s[%d]: AttachCurrentThread ()\n",
+ __FILE__, __LINE__);
+ return -1;
+ }
+
+ jbyteArray byteArray;
+ byteArray = (*env)->NewByteArray(env, datalen);
+ (*env)->SetByteArrayRegion(env, byteArray, 0, datalen, (jbyte *)data);
+
+ // Call socketChannelWrite() in Java
+ jint retVal = (*env)->CallIntMethod(env, obj, ptII_jmethodID_socketChannelWrite, (jobject)socketChannel, byteArray);
+
+ return (int) retVal;
+ }
+
+ // Read from socket.
+ // Returns number of bytes read. 0 if end of stream reached. -1 if error.
+ int ptII_socketChannelRead(void *socketChannel, void *data, int datalen) {
+ jobject obj = ptII_global_obj;
+
+ JNIEnv *env;
+ // Attach the current thread to the JVM if it has not already been
+ // attached and get the environment.
+ if ((*ptII_vm)->AttachCurrentThread(ptII_vm, (void **) &env, NULL) < 0) {
+ fprintf(stderr, "Error in %s[%d]: AttachCurrentThread ()\n",
+ __FILE__, __LINE__);
+ return -1;
+ }
+
+ jbyteArray byteArray;
+ byteArray = (*env)->NewByteArray(env, datalen);
+ //(*env)->SetByteArrayRegion(env, byteArray, 0, datalen, (jbyte *)data);
+
+ // Call socketChannelRead() in Java
+ jint retVal = (*env)->CallIntMethod(env, obj, ptII_jmethodID_socketChannelRead, (jobject)socketChannel, byteArray);
+
+ jbyte *dataRead = (*env)->GetByteArrayElements(env, byteArray, NULL);
+
+ // Copy data into destination pointer.
+ int i;
+ int len = (int) retVal;
+ char *destBuf = data;
+ for (i = 0; i < len; i++) {
+ destBuf[i] = dataRead[i];
+ }
+
+ (*env)->ReleaseByteArrayElements(env, byteArray, dataRead, JNI_ABORT);
+
+ return (int) retVal;
+ }
+
+ /////////////////////// End socket methods ////////////////////////////
+
+
// Create a monitor object (jobject) and return it.
// Returns: an empty jobject
More information about the Tinyos-contrib-commits
mailing list