[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