Example #1
0
    void logentry(std::string& entry, const char* level, const std::string& category)
    {
      struct timeval t;
      gettimeofday(&t, 0);

      // format date only once per second:
      static char date[20];
      static time_t psec = 0;
      time_t sec = static_cast<time_t>(t.tv_sec);
      if (sec != psec)
      {
        struct tm tt;
        localtime_r(&sec, &tt);
        int year = 1900 + tt.tm_year;
        int mon = tt.tm_mon + 1;
        date[0] = static_cast<char>('0' + year / 1000 % 10);
        date[1] = static_cast<char>('0' + year / 100 % 10);
        date[2] = static_cast<char>('0' + year / 10 % 10);
        date[3] = static_cast<char>('0' + year % 10);
        date[4] = '-';
        date[5] = static_cast<char>('0' + mon / 10);
        date[6] = static_cast<char>('0' + mon % 10);
        date[7] = '-';
        date[8] = static_cast<char>('0' + tt.tm_mday / 10);
        date[9] = static_cast<char>('0' + tt.tm_mday % 10);
        date[10] = ' ';
        date[11] = static_cast<char>('0' + tt.tm_hour / 10);
        date[12] = static_cast<char>('0' + tt.tm_hour % 10);
        date[13] = ':';
        date[14] = static_cast<char>('0' + tt.tm_min / 10);
        date[15] = static_cast<char>('0' + tt.tm_min % 10);
        date[16] = ':';
        date[17] = static_cast<char>('0' + tt.tm_sec / 10);
        date[18] = static_cast<char>('0' + tt.tm_sec % 10);
        date[19] = '.';

        psec = sec;
      }

      entry.append(date, 20);

      entry += static_cast<char>('0' + t.tv_usec / 100000 % 10);
      entry += static_cast<char>('0' + t.tv_usec / 10000 % 10);
      entry += static_cast<char>('0' + t.tv_usec / 1000 % 10);
      entry += static_cast<char>('0' + t.tv_usec / 100 % 10);
      entry += static_cast<char>('0' + t.tv_usec / 10 % 10);
      entry += ' ';
      entry += '[';
      char str[64];
      char* p = putInt(str, getpid());
      entry.append(str, p - str);
      entry += '.';
      p = putInt(str, (unsigned long)pthread_self());
      entry.append(str, p - str);
      entry += "] ";
      entry += level;
      entry += ' ';
      entry += category;
      entry += " - ";
    }
Example #2
0
void pick_block(int16_t page) {
    if (page == current_page) {
	return;
    }
    if (current_page != -1) {
	flush_block();
    }
    if (page >= pages_initialized) {
	uint8_t buf[16];
	for (int16_t i = 0; i < 16; ++i) {
	    buf[i] = 0xff;
	}
	for (int16_t i = 0; i < 512; i += 16) {
	    flash_buf_write(0, i, buf, 16);
	}
	for ( ; pages_initialized <= page; ) {
	    flash_put_buffer(0, pages_initialized);
	    pages_initialized++;
	}
	eeprom_write(EEP_MAXPAGE_L, (uint8_t)(pages_initialized & 0xff));
	eeprom_write(EEP_MAXPAGE_H, (uint8_t)(pages_initialized >> 8));
	putProg("Pages initialized: ");
	putInt(pages_initialized);
	putCRLF();
    }
Example #3
0
/**
 * Login Packet Create
 * Populate the backing ByteBuffer with the expected LoginPacket structure as defined in the protocol
 *
 * Struct:
 * INT: Protocol Version
 * INT: Size of Username
 * A_STR: Username
 *
 * @return Byte array of the same size as the ByteBuffer (pkt->size()) of the built packet
 */
byte* LoginPacket::create(bool force) {
	// Check for cached create data
	if(checkCreate(force))
		return createData;

	// Build the packet
	put(OP(LOGIN));
	putInt(PROTOCOL_VERSION); // The protocol version the program was compiled with
	putInt((int)username.size()+1);
	putBytes((byte *)username.c_str(), (int)username.size()+1);

	// Save created data
	saveCreate();

	// Return the created byte array
    return createData;
}
Example #4
0
int net_buffer_putInt(struct net_buffer * buf, uint32_t word)
{
    if (!buf) return -1;
    if ((buf->buf_ptr + sizeof(uint32_t)) > buf->buf+buf->size) return -1;

    putInt(buf->buf_ptr, word);
    buf->buf_ptr += sizeof(uint32_t);
    return 0;
}
Example #5
0
int attachConnectionReadHandler(struct NSNetConnectionController *nscc,
    const struct NSNetConnectionReadHandler *nscch, void *udata)
{
  struct NSNet *ns;
  struct NSNetReadHandlerInternal *newReader;
  ns = nscc->ns;
  newReader = (struct NSNetReadHandlerInternal *)calloc(sizeof(*newReader),1);
  newReader->nsrh = *nscch;
  newReader->udata = udata;
  newReader->fd = nscc->fd;
  newReader->ns = ns;
  putInt(ns->readerMap, nscc->fd, newReader);
  addReadFd(ns, nscc->fd);
  return 0;
}
Example #6
0
int attemptConnect(struct NSNet *ns, const struct NSNetConnectionHandler *nsc,
                    const char *destaddr, unsigned short destPort, void *udata)
{
  int retval;
  int connErrno = 0;
  sock_t fd;
  rsockaddr_t dest;
  if (makeAddress(destaddr, destPort, &dest, nsc, udata)) {
    return 1;
  }
  fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  setNSnonblocking(ns, fd);
  errno = 0;
  retval = connect(fd, (struct sockaddr *) &dest, sizeof(dest));
  if (retval == -1) connErrno = errno;
  if (retval == 0) {
    struct NSNetConnectionController *nscc = calloc(sizeof(*nscc), 1);
    nscc->ns = ns;
    nscc->fd = fd;
    nscc->peer = dest;
    nscc->udata = udata;
    nsc->success(udata, nscc);

    return 0;
  }
  rassert(retval == -1);
  if (connErrno == EINPROGRESS) {
    struct NSNetConnectionHandlerInternal *connectHI;
    connectHI = calloc(sizeof(*connectHI), 1);
    connectHI->ns = ns;
    connectHI->nsc = *nsc;
    connectHI->fd = fd;
    connectHI->dest = dest;
    connectHI->udata = udata;
    addWriteFd(ns, fd);
    addErrFd(ns, fd);
    addReadFd(ns, fd);
    putInt(ns->connectMap, fd, connectHI);
    return 0;
  }
  rassert(0 && "Unkown connect error");
  return 1;
}
Example #7
0
    encode()
    {
        Packet::encode();
        buffer+=ID;
        putInt(seed);
        putByte(dimension);
        putInt(generator);
        putInt(gamemode);
        putLong(eid);
        putInt(spawnX);
        putInt(spawnY);
        putInt(spawnZ);
        putFloat(x);
        putFloat(y);
        putFloat(z);
        putByte('\0');


    }
Example #8
0
int attemptBind(struct NSNet *ns, const struct NSNetBindHandler *nsb,
                int isLocalOnly, unsigned short portNum, void *udata)
{
  struct NSNetBindHandlerInternal *bindHI;

  sock_t sock_fd;
  rsockaddr_t local;
  int retval;
  int one = 1;

  sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (sock_fd < 0) {
    perror("socket");
    nsb->error(udata);
    return 1;
  }
  retval = setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));

  if (retval != 0) {
    perror("setsockopt");
    nsb->error(udata);
    return 1;
  }

  local.sin_family = AF_INET;
  local.sin_port = htons(portNum);
  if (isLocalOnly) {
    retval = inet_aton("127.0.0.1", &local.sin_addr);
    if (retval == 0) {
      perror("inet_aton");
      nsb->error(udata);
      return 1;
    }
  }
  else
    local.sin_addr.s_addr =  INADDR_ANY;

  retval = bind(sock_fd, (struct sockaddr *) &local, sizeof(local));
  if (retval != 0) {
    perror("bind");
    nsb->error(udata);
    return 1;
  }
  retval = listen(sock_fd, MAXCLIENTS);
  if (retval != 0) {
    perror("listen");
    nsb->error(udata);
    return 1;
  }

  addErrFd(ns, sock_fd);
  addReadFd(ns, sock_fd);

  bindHI = calloc(sizeof(*bindHI), 1);
  bindHI->fd = sock_fd;
  bindHI->udata = udata;
  bindHI->nsb = *nsb;

  putInt(ns->bindMap, sock_fd, bindHI);

  return 0;
}
Example #9
0
/*
** Create a new delta.
**
** The delta is written into a preallocated buffer, zDelta, which 
** should be at least 60 bytes longer than the target file, zOut.
** The delta string will be NUL-terminated, but it might also contain
** embedded NUL characters if either the zSrc or zOut files are
** binary.  This function returns the length of the delta string
** in bytes, excluding the final NUL terminator character.
**
** Output Format:
**
** The delta begins with a base64 number followed by a newline.  This
** number is the number of bytes in the TARGET file.  Thus, given a
** delta file z, a program can compute the size of the output file
** simply by reading the first line and decoding the base-64 number
** found there.  The delta_output_size() routine does exactly this.
**
** After the initial size number, the delta consists of a series of
** literal text segments and commands to copy from the SOURCE file.  
** A copy command looks like this:
**
**     NNN@MMM,
**
** where NNN is the number of bytes to be copied and MMM is the offset
** into the source file of the first byte (both base-64).   If NNN is 0
** it means copy the rest of the input file.  Literal text is like this:
**
**     NNN:TTTTT
**
** where NNN is the number of bytes of text (base-64) and TTTTT is the text.
**
** The last term is of the form
**
**     NNN;
**
** In this case, NNN is a 32-bit bigendian checksum of the output file
** that can be used to verify that the delta applied correctly.  All
** numbers are in base-64.
**
** Pure text files generate a pure text delta.  Binary files generate a
** delta that may contain some binary data.
**
** Algorithm:
**
** The encoder first builds a hash table to help it find matching
** patterns in the source file.  16-byte chunks of the source file
** sampled at evenly spaced intervals are used to populate the hash
** table.
**
** Next we begin scanning the target file using a sliding 16-byte
** window.  The hash of the 16-byte window in the target is used to
** search for a matching section in the source file.  When a match
** is found, a copy command is added to the delta.  An effort is
** made to extend the matching section to regions that come before
** and after the 16-byte hash window.  A copy command is only issued
** if the result would use less space that just quoting the text
** literally. Literal text is added to the delta for sections that 
** do not match or which can not be encoded efficiently using copy
** commands.
*/
int delta_create(
  const char *zSrc,      /* The source or pattern file */
  unsigned int lenSrc,   /* Length of the source file */
  const char *zOut,      /* The target file */
  unsigned int lenOut,   /* Length of the target file */
  char *zDelta           /* Write the delta into this buffer */
){
  int i, base;
  char *zOrigDelta = zDelta;
  hash h;
  int nHash;                 /* Number of hash table entries */
  int *landmark;             /* Primary hash table */
  int *collide;              /* Collision chain */
  int lastRead = -1;         /* Last byte of zSrc read by a COPY command */

  /* Add the target file size to the beginning of the delta
  */
  putInt(lenOut, &zDelta);
  *(zDelta++) = '\n';

  /* If the source file is very small, it means that we have no
  ** chance of ever doing a copy command.  Just output a single
  ** literal segment for the entire target and exit.
  */
  if( lenSrc<=NHASH ){
    putInt(lenOut, &zDelta);
    *(zDelta++) = ':';
    memcpy(zDelta, zOut, lenOut);
    zDelta += lenOut;
    putInt(checksum(zOut, lenOut), &zDelta);
    *(zDelta++) = ';';
    return zDelta - zOrigDelta;
  }

  /* Compute the hash table used to locate matching sections in the
  ** source file.
  */
  nHash = lenSrc/NHASH;
  collide = fossil_malloc( nHash*2*sizeof(int) );
  landmark = &collide[nHash];
  memset(landmark, -1, nHash*sizeof(int));
  memset(collide, -1, nHash*sizeof(int));
  for(i=0; i<lenSrc-NHASH; i+=NHASH){
    int hv;
    hash_init(&h, &zSrc[i]);
    hv = hash_32bit(&h) % nHash;
    collide[i/NHASH] = landmark[hv];
    landmark[hv] = i/NHASH;
  }

  /* Begin scanning the target file and generating copy commands and
  ** literal sections of the delta.
  */
  base = 0;    /* We have already generated everything before zOut[base] */
  while( base+NHASH<lenOut ){
    int iSrc, iBlock;
    unsigned int bestCnt, bestOfst=0, bestLitsz=0;
    hash_init(&h, &zOut[base]);
    i = 0;     /* Trying to match a landmark against zOut[base+i] */
    bestCnt = 0;
    while( 1 ){
      int hv;
      int limit = 250;

      hv = hash_32bit(&h) % nHash;
      DEBUG2( printf("LOOKING: %4d [%s]\n", base+i, print16(&zOut[base+i])); )
      iBlock = landmark[hv];
      while( iBlock>=0 && (limit--)>0 ){
        /*
        ** The hash window has identified a potential match against 
        ** landmark block iBlock.  But we need to investigate further.
        ** 
        ** Look for a region in zOut that matches zSrc. Anchor the search
        ** at zSrc[iSrc] and zOut[base+i].  Do not include anything prior to
        ** zOut[base] or after zOut[outLen] nor anything after zSrc[srcLen].
        **
        ** Set cnt equal to the length of the match and set ofst so that
        ** zSrc[ofst] is the first element of the match.  litsz is the number
        ** of characters between zOut[base] and the beginning of the match.
        ** sz will be the overhead (in bytes) needed to encode the copy
        ** command.  Only generate copy command if the overhead of the
        ** copy command is less than the amount of literal text to be copied.
        */
        int cnt, ofst, litsz;
        int j, k, x, y;
        int sz;

        /* Beginning at iSrc, match forwards as far as we can.  j counts
        ** the number of characters that match */
        iSrc = iBlock*NHASH;
        for(j=0, x=iSrc, y=base+i; x<lenSrc && y<lenOut; j++, x++, y++){
          if( zSrc[x]!=zOut[y] ) break;
        }
        j--;

        /* Beginning at iSrc-1, match backwards as far as we can.  k counts
        ** the number of characters that match */
        for(k=1; k<iSrc && k<=i; k++){
          if( zSrc[iSrc-k]!=zOut[base+i-k] ) break;
        }
        k--;

        /* Compute the offset and size of the matching region */
        ofst = iSrc-k;
        cnt = j+k+1;
        litsz = i-k;  /* Number of bytes of literal text before the copy */
        DEBUG2( printf("MATCH %d bytes at %d: [%s] litsz=%d\n",
                        cnt, ofst, print16(&zSrc[ofst]), litsz); )
        /* sz will hold the number of bytes needed to encode the "insert"
        ** command and the copy command, not counting the "insert" text */
        sz = digit_count(i-k)+digit_count(cnt)+digit_count(ofst)+3;
        if( cnt>=sz && cnt>bestCnt ){
          /* Remember this match only if it is the best so far and it
          ** does not increase the file size */
          bestCnt = cnt;
          bestOfst = iSrc-k;
          bestLitsz = litsz;
          DEBUG2( printf("... BEST SO FAR\n"); )
        }

        /* Check the next matching block */
        iBlock = collide[iBlock];
      }
Example #10
0
sp<ByteBuffer> ByteBuffer::putInt(int32_t value) {
    putInt(mPosition, value);
    mPosition += sizeof(value);
    return this;
}
Example #11
0
void convert(std::string& str, unsigned long value)
{
    str.clear();
    putInt(std::back_inserter(str), value);
}
Example #12
0
void convert(std::string& str, int value)
{
    str.clear();
    putInt(std::back_inserter(str), value);
}
Example #13
0
void convert(String& str, signed char value)
{
    str.clear();
    putInt(std::back_inserter(str), value);
}
/**
 * Send an MMS message.
 *
 * @param sendingToSelf <code>1</code> if sending the message to this device;
 *      <code>0</code>, otherwise.
 * @param toAddr The recipient's MMS address.
 * @param fromAddr The sender's MMS address.
 * @param appID The application ID string associated with this message.
 * @param replyToAppID The reply-to application ID string associated with this
 *     message.
 * @param msgLen The total length, in bytes, of the MMS message.
 * @param msg A pointer to the MMS message, which contains both the message
 *     header and message body structures.
 * @param bytesWritten Returns the number of bytes written after successful
 *     write operation. This is only set if this function returns
 *     WMA_NET_SUCCESS.
 *
 * @return WMA_NET_SUCCESS for successful write operation;\n
 *	 WMA_NET_WOULDBLOCK if the operation would block,\n
 *	 WMA_NET_INTERRUPTED for an Interrupted IO Exception\n
 *	 WMA_NET_IOERROR for all other errors.
 */
WMA_STATUS jsr205_mms_write(jint sendingToSelf, char *toAddr, char* fromAddr, 
                               char* appID, char* replyToAppID, jint msgLen, char* msg, 
                               jint *bytesWritten) {

    /** The total length of all data to be written. */
    jint totalLength = 0;

    /** The buffer that will contain all data to be written. */
    char* buffer = NULL;

    /** The writing index. */
    jint index = 0;

    /** The return status. */
    WMA_STATUS status;

    if (appID == NULL) appID = "";
    if (replyToAppID == NULL) replyToAppID = "";

    /*
     * Create storage for the following:
     * - Application ID and its terminator (1 byte)
     * - The 1-byte terminator for the replyToAppID, or the 1-byte
     *   special flag when replyToAppID is NULL.
     * - The message length data
     * - The message data.
     */
    totalLength = strlen(fromAddr) + 1 +
                  strlen(appID) + 1 +
                  strlen(replyToAppID) + 1 +
                  sizeof(int) + msgLen;
    buffer = (char*)pcsl_mem_malloc(totalLength);
    if (buffer == NULL) {
        return WMA_NET_IOERROR;
    }
    memset(buffer, 0, totalLength);

    /* Populate the buffer to be written. */
    putString(buffer, &index, (char*)fromAddr);
    putString(buffer, &index, (char*)appID);
    putString(buffer, &index, (char*)replyToAppID);
    putInt(buffer, &index, msgLen);
    putBytes(buffer, &index, (char *)msg, msgLen);

#if ENABLE_WMA_LOOPBACK
    (void)sendingToSelf;
    (void)toAddr;

    MmsMessage* mms =
        createMmsMessage(fromAddr, appID, replyToAppID, msgLen, msg);

    /* Add the message to the pool. */
    jsr205_mms_pool_add_msg(mms);
    /* Notify all listeners of the new message. */
    jsr205_mms_message_arrival_notifier(mms);

    /* Fake the written count as well as the "sending" status. */
    *bytesWritten = totalLength;
    status = WMA_NET_SUCCESS;

#else
    /* The buffer to be written would have the reply-to address. */
    (void)replyToAppID;

    int outputPort = mmsOutPortNumber;

    if (sendingToSelf != 0) {
        /* Talking to ourselves; redirect output to the in-port. */
        outputPort = mmsInPortNumber;
    }
    status = jsr205_datagram_write(outputPort, mmsHandle, toAddr, fromAddr,
                                   totalLength, buffer, bytesWritten);

#endif

    /* Message was sent, so free the buffer. */
    pcsl_mem_free(buffer);

    return status;
}
/**
 * Write an SMS datagram.
 */
WMA_STATUS jsr120_sms_write(jchar msgType,
                               unsigned char address[],
                               unsigned char msgBuffer[],
                               jchar msgLen,
                               jchar sourcePort,
                               jchar destPort,
                               jint *bytesWritten,
                               void **pContext) {
  
    /** The buffer that will contain all data to be written. */
    char *buffer = NULL;

    /** The writing index. */
    jint index = 0;

    /** The return status. */
    int status = 0;

    /** Internal sms phone number property */
    const char *phNum = NULL;

    /** Physical port to be used to send SMS */
    jint sendPort = smsOutPortNumber; 

    /** Time related structs, variable */
    struct timeval tv;
    jlong timestamp = 0;
    jint tstat = -1;

    (void)sourcePort;
    (void)pContext;

    /* Allocate and initialize datagram buffer */
    buffer = (char*)pcsl_mem_malloc(MAX_DATAGRAM_LENGTH);
    if (buffer == NULL) {
        return WMA_NET_IOERROR;
    }
    memset(buffer, 0, MAX_DATAGRAM_LENGTH);

    /* Get phone number */
    load_var_char_env_prop((char**)&phNum, "JSR_120_PHONE_NUMBER",
        "com.sun.midp.io.j2me.sms.PhoneNumber");

    if (phNum == NULL) {
        /* Free resources and quit */
        pcsl_mem_free(buffer);
        /* Cannot determine device's phone number. Fatal error. */
        return WMA_NET_IOERROR;
    }

    /* Check if SMS is being sent to yourself */
    if (strcmp(phNum, (char *)address) == 0) {
        /*
         * Sending SMS to yourself, swicth port to the one you're 
         * listening on.
         */
        sendPort = smsInPortNumber;
    }

    /* Compute time of sending */
    tstat = gettimeofday(&tv, NULL);
    if (!tstat) { /* Success on getting time of day */
        /* We adjust to 1000 ticks per second */
        timestamp = (jlong)tv.tv_sec * 1000 + tv.tv_usec/1000;
    }

    /* Populate the datagram buffer */
    putInt(buffer, &index, (int)msgType);
    putInt(buffer, &index, (int)destPort);
    putLongLong(buffer, &index, timestamp);
    putString(buffer, &index, (char *)address);
    putString(buffer, &index, (char *)phNum);
    putInt(buffer, &index, (int)msgLen);
    if (msgLen > 0) {
        putBytes(buffer, &index, (char *)msgBuffer, msgLen);
    }

#if ENABLE_WMA_LOOPBACK
    {
        /*
         * This code is enabled mainly for unit tests
         * that want to test send/receive without the
         * network, i.e. message to be sent is put back
         * into the message pool and received by the sender.
         */
        SmsMessage *sms = (SmsMessage *)pcsl_mem_malloc(sizeof(SmsMessage));
        if (sms != NULL) {
            memset(sms, 0, sizeof(SmsMessage));

            sms->encodingType = msgType;
            sms->destPortNum = (unsigned short)destPort;
            sms->timeStamp = timestamp;
            sms->msgAddr = pcsl_mem_strdup((char *)phNum);
            sms->msgLen = msgLen;
            if (msgLen > 0) {
                jint i;
                char *msg = (char*)pcsl_mem_malloc(msgLen + 1);
                for (i = 0; i < msgLen; i++) {
                    msg[i] = msgBuffer[i];
		}
                msg[i] = '\0';
	        sms->msgBuffer = msg;
            }
            /* add message to pool */
           jsr120_sms_pool_add_msg(sms);
           /* Notify all listeners of the new message. */
           jsr120_sms_message_arrival_notifier(sms);

           status = msgLen;
        } else {
           return WMA_NET_IOERROR;
        }

    }
#else
    {
        unsigned char ipAddr[256];
        jint plen = 0;
        struct sockaddr_in addr;

        memset(ipAddr, 0, 256);

        /* Send the datagram into the ether. */
        if (network_gethostbyname(targetHost, ipAddr, 256, &plen) != WMA_NET_SUCCESS) {
            return WMA_NET_IOERROR;
        }

        addr.sin_family = AF_INET;
        addr.sin_port   = htons((unsigned short)sendPort);
        memcpy(&addr.sin_addr.s_addr, ipAddr, sizeof(addr.sin_addr.s_addr));

        status = sendto(wmaGetRawSocketFD(smsHandle), buffer, MAX_DATAGRAM_LENGTH, 0, 
                        (struct sockaddr*)&addr, sizeof(addr));
    }
#endif

    /* Message was sent, so free the buffer. */
    pcsl_mem_free(buffer);

    if (status == SOCKET_ERROR) {
        if ((errno == EWOULDBLOCK) || (errno == EINPROGRESS)) {
            return WMA_NET_WOULDBLOCK;
        } else if (errno == EINTR) {
            return WMA_NET_INTERRUPTED;
        } else {
            return WMA_NET_IOERROR;
        }
    }

    *bytesWritten = status;
    return WMA_NET_SUCCESS;
}
static WMA_STATUS jsr205_datagram_write(jint outPort, void* handle, char *toAddr,
    char* fromAddr, jint length, char* buf, jint *bytesWritten) {

    /** The maximum amount of data allowed within a network packet. */
    jint PACKET_MAX_SIZE = MAX_DATAGRAM_LENGTH - 10;  /* 3 shorts + 1 int */

    /** The socket descriptor that corresponds to the handle. */
    jint socket_fd;

    /** The total number of datagram packets to be sent. */
    jshort totalPackets;

    /** The current packet number. */
    jshort packetNumber;

    /** The IP address used for datagram transfers. */
    unsigned char ipAddr[256];

    /** The length of the IP address to be retrieved. */
    int plen = 0;

    struct sockaddr_in addr;

    /** The buffer for all datagram data. */
    char* dgramBuffer = NULL;

    /** The writing index into the datagram buffer. */
    jint index = 0;

    /** The running pointer to the data to be sent, chunk by chunk. */
    char* p = buf;   /* pointer into buf */

    /** The count of bytes for the current chunk of data to be sent. */
    jint count = 0;

    jint status = WMA_NET_IOERROR;

    /*
     * The "to" and "from" addresses are not used in this implementation. In a
     * more sophisticated implementation that may involve more than one
     * recipient, the packets that get broadcast would need to be directed to
     * specific phones. The "to" address would then come into play and would
     * need to be for each specific phone in a phone list.
     */
    (void)toAddr;
    (void)fromAddr;

    /* Pick up the socket descriptor that corresponds to the handle. */
    socket_fd = wmaGetRawSocketFD(handle);

    *bytesWritten = 0;

    /* Compute the total number of datagrams required to send the message. */
    totalPackets =
        (jshort)((length + PACKET_MAX_SIZE - 1) / PACKET_MAX_SIZE);

    for (packetNumber = 1; packetNumber <= totalPackets; packetNumber++) {

        /** Reset the writing index into the datagram buffer. */
        index = 0;

        if (dgramBuffer == NULL) {
            /* Allocate datagram buffer */
            dgramBuffer = (char*)pcsl_mem_malloc(MAX_DATAGRAM_LENGTH);
        }

        if (dgramBuffer != NULL) {

            /* Initialize the datagram buffer. */
            memset(dgramBuffer, 0, MAX_DATAGRAM_LENGTH);

            /* Compute the number of bytes that can be stuffed into
             * this packet. 
             */
            count = length;
            if (count > PACKET_MAX_SIZE) {
                count = PACKET_MAX_SIZE;
            }

            /* Build the buffer to be written */
            putShort(dgramBuffer, &index, packetNumber);
            putShort(dgramBuffer, &index, totalPackets);
            /* Needed for: count < PACKET_MAX_SIZE */
            putShort(dgramBuffer, &index, count);
            /* Total length of message. */
            putInt(dgramBuffer, &index, length);
            /* Writes count bytes, starting at p. */
            putBytes(dgramBuffer, &index, p, count);

            memset(ipAddr, 0, 256);

            /* Send the datagram into the ether. */
            if (network_gethostbyname(targetHost, ipAddr, 256, &plen)
                != WMA_NET_SUCCESS) {

                return WMA_NET_IOERROR;
            }

            addr.sin_family = AF_INET;
            addr.sin_port   = htons((unsigned short)outPort);
            memcpy(&addr.sin_addr.s_addr, ipAddr,
                   sizeof(addr.sin_addr.s_addr));

            status = sendto(socket_fd, dgramBuffer, MAX_DATAGRAM_LENGTH,
                0, (struct sockaddr*)&addr, sizeof(addr));

            if (SOCKET_ERROR == status) {
                if (EWOULDBLOCK == errno || EINPROGRESS == errno) {
                    status = WMA_NET_WOULDBLOCK;
                } else if (EINTR == errno) {
                    status = WMA_NET_INTERRUPTED;
                } else {
                    status = WMA_NET_IOERROR;
                }
                break;
            }

            *bytesWritten += status;

            status = WMA_NET_SUCCESS;

            /* Move the pointer past the bytes and do next send */
            p += count;
            length -= count;
        }
    }

    /* If a datagram buffer was used, be sure to free its memory. */
    pcsl_mem_free(dgramBuffer);

    return (WMA_STATUS)status;
}