Documentation  |   Table of Contents   |  < Previous   |  Next >   |  Index

10    The ROM Serial Number

System Management

Exploring Palm OS®

Some Palm devices hold a 12-digit serial number that uniquely identifies the device. The serial number is held in a displayable text buffer with no null terminator. The user can view the serial number in the Application Launcher application. The Application Launcher also displays to the user a checksum digit that you can use to validate user entry of the serial number.

To retrieve the ROM serial number programmatically, pass the sysROMTokenSnum selector to the SysGetROMToken() function. If the SysGetROMToken() function returns an error, or if the returned pointer to the buffer is NULL, or if the first byte of the text buffer is 0xFF, then no serial number is available.

The DrawSerialNumOrMessage() function shown in Listing 10.1 retrieves the ROM serial number, calculates the checksum, and draws both on the screen at a specified location. If the device has no serial number, this function draws a message you specify. This function accepts as its input a pair of coordinates at which it draws output, and a pointer to the message it draws when a serial number is not available.

Listing 10.1  DrawSerialNumOrMessage


static void DrawSerialNumOrMessage(Int16 x, Int16 y, Char*
noNumberMessage) 
{ 
   Char* bufP; 
   UInt16* bufLen; 
   Err retval; 
   Int16    count; 
   UInt8    checkSum; 
   Char    checksumStr[2]; 
      // holds the dash and the checksum digit 
  
   retval = SysGetROMToken (0, sysROMTokenSnum, 
      (UInt8**) &bufP, &bufLen); 
   if ((!retval) && (bufP) && ((UInt8) *bufP != 0xFF)) { 
      // there's a valid serial number! 
      // Calculate the checksum:  Start with zero, add each 
      // digit, then rotate the result one bit to the left
      // and repeat. 
         checkSum = 0; 
         for (count=0; count<bufLen; count++) { 
            checkSum += bufP[count]; 
            checkSum = (checkSum<<1) | ((checkSum&0x80)>>7); 
         } 
      // Add the two hex digits (nibbles) together, +2 
      // (range: 2 - 31 ==> 2-9, A-W) 
      // By adding 2 before converting to ascii,
      // we eliminate the numbers 0 and 1, which can be
      // difficult to distinguish from the letters O and I.
      checkSum = ((checkSum>>4) & 0x0F)+(checkSum & 0x0F)+2; 
  
      // draw the serial number and find out how wide it was
      WinDrawChars(bufP, bufLen, x, y);
      x += FntCharsWidth(bufP, bufLen); 
  
      // draw the dash and the checksum digit right after it
      checksumStr[0] = '-';
      checksumStr[1] = 
         ((checkSum < 10) ? (checkSum +'0') : 
         (checkSum -10 +'A'));
      WinDrawChars (checksumStr, 2, x, y);
   } else // there's no serial number
      // draw a status message if the caller provided one
      if (noNumberMessage)
         WinDrawChars(noNumberMessage, 
   StrLen(noNumberMessage),x, y); 
}