Campbell Scientific Proprietary Information. Not to be distributed out of house without express permission from Campbell Scientific, Inc. BMP5 Transparent Commands Revision: 9/08 C o p y r i g h t © 2 0 0 5 - 2 0 0 8 C a m p b e l l S c i e n t i f i c , I n c .
BMP5 Transparent Commands Table of Contents PDF viewers note: These page numbers refer to the printed version of this document. Use the Adobe Acrobat® bookmarks tab for links to specific sections. 1. Introduction...............................................................1-1 1.1 Communication Layers......................................................................... 1-1 1.2 Packet Structure .................................................................................... 1-2 1.2.
BMP5 Transparent Commands Table of Contents 2.3.4 Data Collection and Table Control Transactions ...................... 2-17 2.3.4.1 Table Definitions ............................................................. 2-17 2.3.4.2 Getting Table Definitions and Table Signatures.............. 2-18 2.3.4.3 Collect Data Transaction (MsgType 0x09 & 0x89) ........ 2-19 2.3.4.4 One-Way Data Transaction (MsgType 0x20 & 0x14) .... 2-20 2.3.4.5 Table Control Transaction (MsgType 0x19 & 0x99) ...... 2-22 2.3.
BMP5 Transparent Commands Table of Contents 4.11 Collecting Files from the Datalogger................................................ 4-11 4.12 Controlling Packet Size .................................................................... 4-11 Appendices A. Data Types Summary ............................................. A-1 B. Calculating Packet Signatures and the Signature Nullifier................................................. B-1 C. Device Description Files.........................................
BMP5 Transparent Commands Table of Contents iv
Section 1. Introduction This document outlines the structure for a fundamental subset of protocols and packet types used to communicate directly with a single PAKBUS® datalogger. The protocols and packet types discussed in this document are collectively referred to as BMP5 and are used to communicate with Campbell Scientific’s native PakBus dataloggers (CR200 Series, CR1000, CR3000, etc.). This documentation assumes the communication link to the datalogger has already been established.
Section 1. Introduction 1.2 Packet Structure 1 byte Header (8 bytes) Message (0...
Section 1. Introduction To ensure that a SerSyncByte doesn’t appear inadvertently within the message data, it must be recognized and quoted within the body of the packet before the packet is transmitted. The quoting process is accomplished by replacing reserved bytes with a special code called the QuoteByte.
Section 1. Introduction 1.4 Encoding and Decoding Packets Reserved characters must be acknowledged and quoted by the application before sending a packet and also recognized and decoded before the application processes a packet. These reserved characters are the SerSyncByte, 0xbd, and the QuoteByte, 0xbc. When these special characters are found within the message body or signature nullifier, they must be handled appropriately. 1.4.
Section 1. Introduction processing the packet information, the application should make the following checks: 1. Check the length of the packet. If the entire packet length is less than 4 bytes or greater than 1010 bytes, it should be considered invalid and discarded. 2. The DstPhyAddr and DstNodeId fields within the packet header should both equal the address of the application or the broadcast address. 3.
Section 1. Introduction This is a blank page.
Section 2. Protocols and Packet Types Packet types from three distinct protocols are described in this document. The SerPkt Protcol used to monitor the state of the communication link, the PakBus Control Protocol (PakCtrl) used to facilitate PakBus network-level services, and the BMP5 Protocol used to send application messages. 2.1 SerPkt Link-State Sub Protocol SerPkt protocol allows the application and the datalogger to track and control the state of their communication link on the network.
Section 2. Protocols and Packet Types Link-State Sub-protocol Packet Format: Name LinkState Type bits7..4 DstPhyAddr ExpMoreCode 12 bits bits 7..6 Priority bits 5..4 SrcPhyAddr { HiProtoCode DstPBAddr HopCnt SrcPBAddr { MsgData }} 12 bits bits 7..4 12 bits bits 7..
Section 2. Protocols and Packet Types Delivery Failure Message Format (MsgType 0x81): Name MsgType TranNbr ErrCode Type Byte Byte Byte HiProtoCode bits 7..4 DstPBAddr 12 bits HopCnt SrcPBAddr MsgData bits 7..4 12 bits Byte [0..
Section 2.
Section 2. Protocols and Packet Types Hello Request Message Format (MsgType 0x0e): Name MsgType TranNbr Type Byte Byte Description Message type code (0x0e) Transaction number (always zero) 2.2.4 Bye Message (MsgType 0x0d) The Bye Message is a one-way message that lets a node on the network know that the link is shutting down and that the nodes will no longer be able to talk to each other. Before shutting down a link, like a phone modem connection, it is good practice to always send a Bye Message.
Section 2. Protocols and Packet Types Set Settings Command Message (MsgType 0x08): Name MsgType TranNbr Settings Type Byte Byte ASCIIZ Description Message type code (0x08) Transaction number A string containing a list of name-value pairs with each name separated by the value with the “=” sign. Each value-pair is separated with a semi-colon.
Section 2. Protocols and Packet Types As datalogger operating systems are revised, these settings may change or be removed. However, the datalogger will always report the major version number within the setting response message so that an application can be aware of the current operating system in the datalogger. By knowing the data type and version number, an application can verify the most current settings for a datalogger with the CR1000 Device Description File located in the Appendix of this document.
Section 2. Protocols and Packet Types Name MoreSettings Type Boolean { SettingId LargeValue UInt2 bit 15 ReadOnly SettingLen bit 14 bit 13..0 SettingValue }} Byte [1..
Section 2. Protocols and Packet Types Name SettingsOutcome } Type Byte Description Specifies the outcome of the set attempt: 0x01: Setting value tagged to be changed 0x02: Setting identifier was not recognized 0x03: Setting value malformed or out of range 0x04: Setting is read-only 0x05: Not enough memory to store the setting 2.2.6.3 DevConfig Get Setting Fragment Transaction Message (MsgType 0x11 & 0x91) The Get Setting Fragment transaction allows an application to ask for part of a setting value.
Section 2. Protocols and Packet Types DevConfig Set Setting Fragment Command (MsgType 0x12): Name MsgType TranNbr SecurityCode SettingId Type Byte Byte UInt2 UInt2 FragmentOffset MoreFragments UInt4 bit 15 FragmentLen bits 14..
Section 2. Protocols and Packet Types Name Action Type Byte Description The action that should be taken by the datalogger 0x01: Commit the changes and exit 0x02: Cancel any changes and exit back to a mode where a new session can be started 0x03: Revert all settings to factory defaults.
Section 2. Protocols and Packet Types 2.3.1 Please Wait Message (MsgType 0xa1) If the datalogger anticipates it will take more than the default one second to produce a response after receiving a command, a Please Wait message will be sent to the client indicating the amount of time the client should wait for a response to that command. The transaction number of the Please Wait message will be the same as the command packet on which it is waiting.
Section 2. Protocols and Packet Types Clock Response Body (MsgType 0x97): Name MsgType TranNbr RespCode Type Byte Byte Byte { OldTime } Nsec Description Message type code (0x97) Transaction number Response code: 0x00: Complete 0x01: Permission denied Difference between the datalogger clock and January 1, 1990. This field is not returned unless RespCode is zero. 2.3.
Section 2. Protocols and Packet Types Name FileOffset Type UInt4 { FileData } Byte [ ] Description Describes the byte offset into the file of this fragment. This field will be zero if this is a single exchange transaction.
Section 2. Protocols and Packet Types Name RespCode Type Byte FileOffset { FileData } UInt4 Byte [ ] Description Response Code: 0x00 – Complete 0x01 – Permission denied 0x0d – Invalid file name 0x0e – File is not currently accessible Byte offset into the file of this fragment The file data beginning at FileOffset. If an attempt was made to read past the end of the file, then this field will be empty or smaller than size requested in the Swath parameter of the command message. 2.3.3.
Section 2. Protocols and Packet Types Name FileCmd Type Byte Description Code that specifies the command to perform with the file: 0x01: Compile and run the program and also make it the “run on power-up” file 0x02: Set the “run on power-up” attribute. When used with an empty file name argument, the “run on power-up” attribute will be cleared.
Section 2. Protocols and Packet Types 2.3.3.5 Get Programming Statistics Transaction (MsgType 0x18 & 0x98) The Get Programming Statistics transaction retrieves available status information from the datalogger.
Section 2. Protocols and Packet Types Data transaction and to describe what data should be returned when collecting data from a datalogger. 2.3.4.2 Getting Table Definitions and Table Signatures Table definitions are obtained using a File Upload transaction and are contained in a file with a “.TDF” file extension. The application only needs to specify the name “.
Section 2. Protocols and Packet Types In order to ensure the integrity of this table information, the application should calculate a signature of the parameters contained in each table within the table definitions. One signature should be calculated for each defined table and should be stored and used by the application to verify that the table has not changed when collecting data. The signature is calculated using the parameters for each table from the Get Table Definitions response.
Section 2. Protocols and Packet Types When a response comes in from this command, the fields after RespCode exist only if the response indicates the transaction completed. If the response to the Collect Data Command sets the parameter IsOffset equal to one, the client must retrieve the remaining fragments of the record by using collect mode 0x08. The client should know the size of the record and therefore know when the entire record has been collected.
Section 2. Protocols and Packet Types Table definitions may be sent from the datalogger to the application prior to the first transmission of a one-way data message and periodically thereafter. Use the table definitions to calculate the table signatures for each table in the same manner as the standard data collection process.
Section 2. Protocols and Packet Types One-Way Data Message Body (MsgType 0x14): Name MsgType TranNbr TableNbr TableDefSig RecNbr IsOffset Type Byte Byte UInt2 UInt2 UInt4 bit 7 NbrOfRecs 15 or 31 bits { TimeOfRec } Sec, USec, or NSec RecFrag Byte [ ] Description Message type code (0x14) Transaction number Table number Table definition signature Record number of this record A flag that, if true, indicates this message contains a fragment of a single record.
Section 2. Protocols and Packet Types 2.3.5 Get/Set Values Transaction (MsgType 0x1a, 0x9a, 0x1b, & 0x9b) These transactions are used to read or write values in the datalogger table. Values are referenced by table and field name. The table definitions can be used to get table and field names from a datalogger if they are not known.
Section 2.
Section 3. The CR200 Datalogger The CR200 is low-cost, rugged, and versatile measurement device. This small datalogger contains a CPU and both digital and analog inputs and outputs. The CR200 has a PakBus operating system that communicates via the BMP5 message protocol. Pre-compiled programs sent to the datalogger are written in a BASIC-like language that includes data processing and analysis routines. These programs run on a precise execution interval and will store measurements and data in tables.
Section 3. The CR200 Datalogger An example of a “Ready” response from a datalogger with an address of 1 to an application with an address of 4094 letting the application know it can proceed with communication is as follows: BD AF FE 00 01 5A 89 BD The datalogger may not be aware that a connection has been established from the PC when beginning the initial communication process.
Section 3. The CR200 Datalogger • PakBusAddress: The PakBus address of the datalogger If the names of the available settings are not known, all settings within the CR200 datalogger can be obtained by specifying a null NameList parameter in a Get Settings transaction. Once the settings are returned, they can be parsed, viewed, and later used as needed. 3.
Section 3. The CR200 Datalogger 3.7 Creating CR200 Programs and the CR200 Compiler The CR200 datalogger must contain a valid program in order to execute instructions that measure and analyze sensor data. These programs are usually generated with either a software program called Short Cut for Windows or with a program editor called CRBasic Editor but if the correct syntax is used, datalogger programs can be written with any text editor.
Section 3. The CR200 Datalogger 3.7.2 Sending a Program to the CR200 The compiled datalogger program is sent to the CR200 with the File Download transaction. The FileName parameter of this transaction describes the file name and location in datalogger memory where the datalogger program should be stored. The compiled datalogger program will always have an extension of “.bin”. An example of the FileName parameter is “CPU:CR200Program.bin”. In addition, the attributes of the file should be specified.
Section 3.
Section 3. The CR200 Datalogger Use the File Control Command with a FileCmd parameter of 0x08 to stop the program currently running on the datalogger. Check the File Control Response. If the RespCode returns a zero, determine the amount of time to wait as declared in the HoldOff parameter before continue the process. Otherwise, report and act on the error result. Use the File Download Command message to send the new program file to the datalogger. The new program file must have the “.BIN” file extension.
Section 3. The CR200 Datalogger latency varies across different communication mediums but the application should be aware of this variability and set the maximum retry interval accordingly. 3.8 Understanding Table Definitions and Table Signatures Since the CR200 stores data in tables, the datalogger and the application must understand and agree on the structure of each table in order to collect data. Table definitions contain the parameters that describe each table, record, and field in the datalogger.
Section 3. The CR200 Datalogger Response packet. Calculate the signature by starting with the first byte of the FieldName parameter and ending after the field list terminator for that table. A description of the signature algorithm and example C code showing the method used to calculate the signature can be found in Appendix B. Additional examples showing functions used to parse tables from table definitions and calculate signatures existing in the JAVA code found in Appendix D.
Section 3. The CR200 Datalogger 3.10.3 Collecting Tables and Specific Records Within the Collect Data Command message there are many options for data collection. The CollectMode parameter of this packet describes what records will be collected from the defined tables. Some collect mode options include: 3-10 CollectMode 0x03: Collect from the oldest record to the newest record starting with the oldest data in each table. This method of collection would be used to collect entire data tables.
Section 3. The CR200 Datalogger 3.10.4 Getting Values from Specific Records Use either the Collect Data Command or the Get Values transaction when attempting to collect a specific value or swath of values from an individual record. These values are referenced by the table and field name, which can be found in the table definitions collected from a station if the user does not already know them.
Section 3. The CR200 Datalogger This is a blank page.
Section 4. The CR1000 Type Datalogger The CR1000 type datalogger (CR1000, CR3000, and CR800) is a rugged and versatile measurement device. This datalogger contains a CPU and both digital and analog inputs and outputs. The CR1000 type datalogger uses a PakBus operating system and communicates with applications via the BMP5 message protocol. Programs sent to the datalogger are written in a BASIC-like language that includes data processing and analysis routines.
Section 4. The CR1000 Type Datalogger BD AF FE 00 01 5A 89 BD The datalogger may not be aware that a connection has been established from the PC when beginning the initial communication process. The application should initiate communication to the CR1000 by sending a series of 0xbd SerSyncBytes before the initial packet to wake up the datalogger, clear the communication buffer, and determine the communication baud rate.
Section 4. The CR1000 Type Datalogger settings for this and other operating systems by reviewing the included Device Description File in Appendix C. Setting ID 0 1 2 3 4 Name OS Version Serial Number Station Name PakBus Address Security 4.5 Getting and Setting the Clock The CR1000 type datalogger contains a precise clock that drives the execution interval of the running program. An application can either check or set the datalogger clock with the Clock Transaction.
Section 4. The CR1000 Type Datalogger 4.7 Sending a Program to the Datalogger The CR1000 type datalogger accepts text programs written with CRBasic syntax and automatically compiles these programs before running them. As long as the program contains correct CRBasic syntax, the datalogger should compile and run the program. Use the File Download transaction to send the program from the application to the datalogger. The file name and device memory location must be specified.
Section 4. The CR1000 Type Datalogger Use the File Download Command message to send the new program file to the datalogger. The new program file must have the “.CR1” file extension. If the program is larger than the MaxPktSize of the datalogger, it should be separated into packets that will fit into the MaxPktSize. After sending each packet, the application should check the RespCode and FileOffset parameters for errors.
Section 4. The CR1000 Type Datalogger files, and start the new program on the datalogger. Check the File Control Response. If the RespCode returns a zero, determine the amount of time to wait as declared in the HoldOff parameter and wait at lest that amount of time before continuing the process. Otherwise, report and act on the error message. Send the Get Programming Statistics transaction and obtain compile results to verify the new datalogger program information.
Section 4. The CR1000 Type Datalogger 4.7.4 Deleting Program Files When loading a new datalogger program to the CR1000 type datalogger, the old datalogger program can remain in datalogger memory for future use or reference. Although data tables are recreated and the data for the currently running program will be lost when a new program begins running on the datalogger, the old program does not have to be deleted.
Section 4. The CR1000 Type Datalogger 4.9 Getting Table Definitions Table definitions are retrieved from the CR1000 type datalogger with the File Upload transaction. The file name in the transaction should be specified as “.TDF”. The datalogger will recognize this file extension and return the appropriate response containing the table definitions.
Section 4. The CR1000 Type Datalogger The response packet from the datalogger will contain data that must be parsed. The application uses table definition information to understand the data structure in the packet in order to extract the appropriate information from the response packet. 4.10.1 Interpreting Data Types The data type determines how each value should be handled by the application.
Section 4. The CR1000 Type Datalogger 4.10.4 Getting Values from Specific records Use either the Collect Data Command or the Get Values transaction when attempting to collect a specific value or swath of values from an individual record. These values are referenced by the table and field name, which can be found in the table definitions collected from a station if the user does not already know them.
Section 4. The CR1000 Type Datalogger 4.11 Collecting Files from the Datalogger The CR1000 type datalogger can store files in memory for future use or retrieval. The list of files contained in datalogger memory can be obtained by requesting a file name of “.DIR” with the File Upload transaction. The datalogger responds with a list of files that are stored on the datalogger.
Section 4. The CR1000 Type Datalogger This is a blank page.
Appendix A.
Appendix A. Data Types Summary This is a blank page.
Appendix B. Calculating Packet Signatures and the Signature Nullifier The CSI signature algorithm, when applied to a block of data, produces a unique value that is a function of the specific sequence and number of bytes under consideration. It is a simple algorithm used in a similar manner as a Cyclic-Redundancy-Check (CRC). We use the signature algorithm instead of the CRC primarily for historic reasons. The following block of code is an example implementation of the signature algorithm in C.
Appendix B. Calculating Packet Signatures and the Signature Nullifier uint2 new_seed = (sig << 1)&0x1FF; byte null1; uint2 new_sig = sig; if(new_seed >= 0x0100) new_seed++; null1 = (byte)(0x0100 - (new_seed + (sig >> 8))); new_sig = calcSigFor(&null1,1,sig); // now perform the same calculation for the most significant byte // in the signature.
Appendix C. Device Description Files Applications that need to deal with device settings must reference a library of device description XML files. These files are identified with a “.dd” extension and are subject to change with new versions of the CR1000 type datalogger operating systems. Each file includes the following information about a device: 1. The device’s device type code 2. The common model number for that device 3. Information about the protocol used to configure the device 4.
Appendix C. Device Description Files Specifies a name assigned to this station. Specifies the PakBus address of the CR1000. Specifies Level 1 Security.
Appendix C.
Appendix C.
Appendix C.
Appendix C.
Appendix D. JAVA Example Code import java.io.*; import java.util.*; import java.net.*; /** * A simple PakBus command line application * that demonstrates how to communicate with a CR200 datalogger * * @author Campbell Scientific, Inc. * @version 1.
Appendix D. JAVA Example Code /** * Application main */ public static void main(String[] args) { try { socket = new Socket("63.255.173.242", 23); socket.setTcpNoDelay(true); //The input streams and output streams are used through out //this example for handling //communication to/from the datalogger. In this //example we are getting these streams //from a socket, but the same streams can be initialized //to talk over serial IO as well.
Appendix D. JAVA Example Code case (0x9d) : // Response for Upload Command System.out.println("Response for Upload Command"); ParseTblDefs(); break; } } } else if(stdin.ready()) { switch(stdin.read()) { case '1': file_offset = 0; tabledefloop = 0; TableDefStr = new String(); System.out.
Appendix D. JAVA Example Code case '8': System.out.println("Getting 24 hour data"); GetTable("Data1",24); SendPb(); break; case '9': NameList = "Model\0"; GetCommand(); SendPb(); break; case 'h': startscreen(); break; case 'x': shouldExit = true; break; default: break; } } } } catch ( IOException e ) { System.err.println(e); } System.out.println("System Shutting Down"); try { stdin.close(); } catch( IOException e ){ System.err.println(e); } } /** * Internal - Used to display the console menu.
Appendix D. JAVA Example Code //SetupDl gets the PakBusAddress by using the GetCommand procedure public static void SetupDL() { GetCommandStatus = 0; NameList = "\0"; GetCommand(); SendPb(); } /** * GetLoggerAddress will broadcast the network to get a response * from the DL to get the pakbus address. This will not work for * multiple DL's they will all respond */ public static void GetCommand() { CreateHeader(); out_packet.hi_protocol_code = Packet.protocol_pakctrl; out_packet.
Appendix D. JAVA Example Code /** * Calculates the signature for a byte. */ static char calcSigForByte(byte buff, char seed) { char rtn = (char)seed; char j = rtn; rtn = (char)((rtn << 1) & (char)0x01FF); if(rtn >= (int)0x100) rtn++; rtn = (char)(((rtn + (j >> 8) + buff) & (char)0xFF) | (j << 8)); return rtn; } // calcSigForByte /** * calculates the signature nullifier */ static char calcSigNullifier(char sig) { //calculate the value for the most significant byte.
Appendix D. JAVA Example Code send_byte((byte)0xBD); // first synch byte for(int i = 0; i < frame.length; ++i) { if(frame[i] == 0xBC || frame[i] == 0xBD) { send_byte((byte)0xBC); send_byte((byte)(frame[i] + 0x20)); } else send_byte(frame[i]); } send_byte((byte)0xBD); out_stream.flush(); } catch(IOException e) { System.out.println("SendPb(): " + e); } } /** * GetPublicValues will create the packet to get the Public table, * it will use the get value command and just get a swath.
Appendix D. JAVA Example Code /** * GetClock will create the packet to * the DL. Thecode that is commented * doing the sigNullifier but it does * the quote chars. */ public static void GetClock() { CreateHeader(); out_packet.message_type = 0x17; out_packet.tran_no = 0x17; out_packet.add_short((short)0); // out_packet.add_int(sendseconds); out_packet.
Appendix D. JAVA Example Code if(table != null) { // form the command message to poll the table CreateHeader(); out_packet.message_type = 0x09; out_packet.tran_no = 0x09; out_packet.add_short((short)0); // security code out_packet.add_byte((byte)5); // collect most recent records out_packet.add_short((short)table.table_no); out_packet.add_short((short)table.def_sig); out_packet.add_int(num_records); // specify the number of // records to return out_packet.
Appendix D. JAVA Example Code catch(Exception e) { flush_io_log(e.toString()); read_index = 0; getlinesig = 0xAAAA; } } else { read_index = 0; getlinesig = 0xAAAA; } } } } catch(IOException e) { System.out.
Appendix D. JAVA Example Code /** * This procedure allows the clock to receive the clock from the logger * and then make the calculations for the difference of the setting time and the * dl time. */ static void SetClkCnts() { switch(setclockcnt) { case (1): sendseconds = (int)((PCtime.getTimeInMillis() DLtime.getTimeInMillis()) / msecPerSec); System.out.
Appendix D. JAVA Example Code static void ParseTblDefs() { try { int logger_resp = in_packet.read_byte(); if(logger_resp == 0) { int returned_offset = in_packet.read_int(); byte[] fragment = in_packet.read_bytes(in_packet.whats_left()); if(table_defs_buffer == null) table_defs_buffer = new Packet(); table_defs_buffer.add_bytes(fragment,fragment.length); file_offset += fragment.length; if(fragment.length == 128) { System.out.
Appendix D. JAVA Example Code static void ParsePublicTbl() { try { int logger_resp = in_packet.read_byte(); if(logger_resp == 0) { System.out.print("Values from table public: "); while(in_packet.whats_left() >= 4) { System.out.print(in_packet.read_float()); if(in_packet.whats_left() >= 4) System.out.print(" "); } System.out.println(""); } else System.out.println("ParsePublicTbl logger error: " + logger_resp); } catch(Exception e) { System.out.println("ParsePublicTbl error: " + e.
Appendix D. JAVA Example Code table != null) { System.out.println("Querying for more data at record " + last_record_no); CreateHeader(); out_packet.message_type = 0x09; out_packet.tran_no = 0x09; out_packet.add_short((short)0); // security code out_packet.add_byte((byte)4); // collect from p1 to newest out_packet.add_short((short)table.table_no); out_packet.add_short((short)table.def_sig); out_packet.add_int(last_record_no + 1); out_packet.add_short((short)0); // send all fields SendPb(); } } else System.
Appendix D. JAVA Example Code private static void log_io(byte val, boolean transmitted) { if(io_last_tx != transmitted && io_log_len > 0) flush_io_log(""); io_log[io_log_len++] = val; io_last_tx = transmitted; if(io_log_len == io_log.length) flush_io_log(""); } private static void send_byte(byte val) throws IOException { log_io(val,true); out_stream.write(val); } private static int read_byte() throws IOException { int rtn = in_stream.
Appendix D. JAVA Example Code /** * Returns milliseconds elapsed since start or reset. * * @return elapsed milliseconds since start or reset * @see #Counter() * @see #reset() */ public int elapsed() { return diff( counter(), start ); } /** * Set the specified value as the start time. * * @param msec value to set as new start time */ public void setStart( int msec ) { this.
Appendix D.
Appendix D. JAVA Example Code // the message type and transaction number may not be present. // We will set them to 0 and then look for them tran_no = 0; message_type = 0; storage_len = 0; if(len >= 9) { message_type = buff[8]; tran_no = buff[9]; storage = new byte[len - 10]; for(int i = 10; i < len; ++i) { ++storage_len; storage[i - 10] = buff[i]; } } } protected void reserve(int len) { // we need to check to make sure that the buffer has the // capacity for the specified length.
Appendix D. JAVA Example Code public void add_short(Short val) { byte[] temp = new byte[2]; temp[0] = (byte)((val & 0xFF00) >> 8); temp[1] = (byte)(val & 0x00FF); add_bytes(temp,temp.length); } public void add_int(Integer val) { byte[] temp = new byte[4]; temp[0] = (byte)((val & 0xFF000000) >> 24); temp[1] = (byte)((val & 0x00FF0000) >> 16); temp[2] = (byte)((val & 0x0000FF00) >> 8); temp[3] = (byte)(val & 0x000000FF); add_bytes(temp,temp.length); } public void add_string(String val) { byte[] temp = val.
Appendix D. JAVA Example Code public int read_int() throws Exception { byte[] temp = read_bytes(4); int rtn = (((int)temp[0] & 0xff) << 24) | (((int)temp[1] & 0xff) << 16) | (((int)temp[2] & 0xff) << 8) | ((int)temp[3] & 0xff); return rtn; } public float read_float() throws Exception { int int_val = read_int(); return Float.
Appendix D.
Appendix D. JAVA Example Code read_only = false; column_name = msg.read_string(); System.out.println("Reading column " + column_name); alias = msg.read_string(); while(alias.length() > 0) alias = msg.read_string(); processing = msg.read_string(); units = msg.read_string(); description = msg.read_string(); begin_index = msg.read_int(); piece_size = msg.read_int(); // we'll ignore the dimensions information and treat everything as // a single dimensioned array.
Appendix D. JAVA Example Code columns = new Vector(); while(field_type != 0) { ColumnDef column = new ColumnDef(column_no,field_type,msg); System.out.println("Read " + table_name + "." + column.column_name); columns.addElement(column); field_type = msg.read_byte(); ++column_no; } // // // // the final thing that we need is to calculate the signature of the table definition.
Appendix D. JAVA Example Code switch(column.field_type) { case type_uint1: { int val = ((int)msg.read_byte()) & 0xff; System.out.println(val); break; } case type_uint2: { int val = ((int)msg.read_short()) & 0xffff; System.out.println(val); break; } case type_uint4: { long val = ((long)msg.read_int()) & 0xffffffffL; System.out.println(val); break; } case type_int1: System.out.println(msg.read_byte()); break; case type_int2: System.out.println(msg.read_short()); break; case type_int4: System.out.println(msg.
Appendix D. JAVA Example Code case type_ascii: { // we need to read off all of the possible bytes for the // string field from the data message. This way, the // pointer will be positioned at the right loc for the // next field. byte[] temp = msg.read_bytes(column.piece_size); k += column.piece_size; // short circuit //loop for strings for(int m = 0; m < temp.length && temp[m] != 0; ++m) System.out.print((char)temp[m]); System.out.println(""); break; } case type_int2_lsf: System.out.
Appendix D.
Glossary ASCII: Acronym for the American Standard Code for Information Interchange that represents the English characters as numbers, with each character assigned a number from 0 to 127. ASCIIZ: An ASCII string that is terminated with a NULL character sequence Binary: The numbering system computers are based on using just two unique numbers: one and zero. BMP5 Protocol: Block Mode Protocol, Version 5. A high-level or application layer protocol used to send messages between nodes over a PakBus network.
This is a blank page
This is a blank page.
Campbell Scientific Companies Campbell Scientific, Inc. (CSI) 815 West 1800 North Logan, Utah 84321 UNITED STATES www.campbellsci.com info@campbellsci.com Campbell Scientific Africa Pty. Ltd. (CSAf) PO Box 2450 Somerset West 7129 SOUTH AFRICA www.csafrica.co.za cleroux@csafrica.co.za Campbell Scientific Australia Pty. Ltd. (CSA) PO Box 444 Thuringowa Central QLD 4812 AUSTRALIA www.campbellsci.com.au info@campbellsci.com.au Campbell Scientific do Brazil Ltda.