Session 2640 Introduction to the iot protocol, mqtt
Upcoming SlideShare
Loading in...5

Like this? Share it with your network


Session 2640 Introduction to the iot protocol, mqtt



MQTT is a simple, event-driven messaging protocol designed for use in Internet of Things and mobile applications. It's implemented in IBM MessageSight and MQ. It's being developed into a standard and ...

MQTT is a simple, event-driven messaging protocol designed for use in Internet of Things and mobile applications. It's implemented in IBM MessageSight and MQ. It's being developed into a standard and is being used more and more in the world at large. Come along to this unashamedly technical session to learn about what the protocol actually does and how to program to it in Java, C, or JavaScript.



Total Views
Views on SlideShare
Embed Views



3 Embeds 23 19 3 1



Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment

Session 2640 Introduction to the iot protocol, mqtt Presentation Transcript

  • 1. Session 2640 Introduction to the IoT protocol, MQTT Peter Niblett IBM Senior Technical Staff Member
  • 2. The Internet of Things is the next Internet Frontier Source:
  • 3. What is MQTT? What is it for? How does it compare with HTTP? Details of MQTT Protocol features Example data flows Developing with MQTT What you need Java and JavaScript API walkthrough
  • 4. An Open Approach to Connectivity for Mobile and IoT MQTT is a lightweight publish/subscribe protocol with reliable bi-directional message delivery Lossy or Constrained Network Lossy or Constrained Network Monitoring & Analytics Server Real-World Aware Business Processing High volumes of data/events IT Systems In this arena, open source and standards are essential 1999 Invented by Dr. Andy Stanford-Clark (IBM), Arlen Nipper (now Cirrus Link Solutions) 2011 - Eclipse PAHO MQTT open source project 2004 open community 2013 – MQTT Technical Committee formed Cimetrics, Cisco, Eclipse, dc-Square, Eurotech, IBM, INETCO Landis & Gyr, LSI, Kaazing, M2Mi, Red Hat, Solace, Telit Comms, Software AG, TIBCO, WSO2 Evolution of an open technology
  • 5. Sense and ControlSense and ControlVisualise and RespondVisualise and Respond Mobile Web Intelligence and Analytics Intelligence and Analytics Interconnect with MQ and MessageSight Traditional Backend Systems Traditional Backend Systems BigDataBigData Sense Data/Alert Respond Control Sensor Area Network Home Area Network Personal Area Network Vehicle Area Network Sensor Area Network Home Area Network Personal Area Network Vehicle Area Network Sensors Actuators Applications MQTT MQTT-SN MQ… Edge Gateway The Role of MQTT
  • 6. Central Systems Monitoring - temp, pressure... Control - valves… 4000 devices integrated, need to add 8000 more BUT: • Satellite network saturated due to polling of device • VALMET system CPU at 100% • Other applications needed access to data ("SCADA prison") Proprietary polling protocol Billing Maintenance SCADA low-bandwidth, expensive comms Real Life - Pipeline integration challenges
  • 7. Central Systems Billing Maintenance SCADA low-bandwidth, expensive comms Scalability for whole pipeline! Network traffic much lower - events pushed to/from devices and report by exception Network cost reduced Lower CPU utilization Broken out of the SCADA prison – data accessible to other applications Message Broker pub sub transformation Enterprise MessagingMQTT 20 Field Devices to 1 Concentrator Enterprise to physical world solution with MQTT
  • 8. MQTT – Key things to remember • Capabilities – One-many publish / Subscribe – Reliable store+forward – Bidirectional communications – Long-running connections • Decoupling – Easy to add new message producers or consumers • Simplicity – Small protocol, small clients (kBytes) – Implementable on low power devices • Network efficiency – Small headers – Avoids polling • Event-orientation – Near real-time notification of events
  • 9. A producer publishes a message (publication) on a topic (subject) A consumer subscribes (makes a subscription) for messages on a topic (subject) A message server matches publications to subscriptions If none of them match the message is discarded If one or more matches the message is delivered to each matching consumer Publish / Subscribe has three important characteristics: 1. It decouples message senders and receivers, allowing for more flexible applications 2. It can take a single message and distribute it to many consumers 3. This collection of consumers can change over time, and vary based on the nature of the message. Publish / Subscribe Messaging (One to Many)
  • 10. Action HTTP MQTT Get single piece of data 302 bytes 69 bytes (<4 times) Send single piece of data 320 bytes 47 bytes (<6 times) Get 100 pieces of data 12600 bytes 2445 bytes (<5 times) Send 100 pieces of data 14100 bytes 2126 bytes (<6 times) Battery Use 3G Wifi HTTPS 0.333% 0.027% MQTT 0.160% 0.002% • MQTT’s very compact wire format, results in lower network costs than an HTTP equivalent • Lightweight footprint – protocol will run on low power devices • Clients: C = 80kb; Java = 100kb JavaScript = 80kb • Recovery, store and forward, and publish/subscribe are all provided by the MQTT implementations, and don’t have to be coded into application logic • Simple set of verbs, easy for developers to learn • Easy integration with Systems of Record Lower development costsLower development costs Lower running costsLower running costs • Near real-time push of information • Minimal battery usage • Store and forward messaging • Exactly once delivery (where required) • MQTT’s Event-Driven design point means that a single server can support a million connected users or devices • Publish/Subscribe allows additional functionality to be added without change to existing application code More Flexibility and ScaleMore Flexibility and Scale Improved User ExperienceImproved User Experience Reasons to use MQTT
  • 11. Details of the MQTT Protocol - Protocol features - Example packet flows
  • 12. MQTT Protocol Deep Dive - Headers MQTT protocol control packets: • Fixed header (2 bytes) • Variable header (optional, length varies) • Message payload (optional, length encoded, up to 256MB) Fixed header indicates the packet type, the length of the payload and Quality of Service Variable header contents depend on packet type • Message ID, Topic name, client identifier and so on. Fixed Variable Payload
  • 13. A 2 byte packet? What can we do with that?! Each bit in each byte is important! Disconnect and pings only need the fixed header Remaining length allows for a 256MB payload • Use 1 byte for up to 127 bytes, • 2 bytes for up to 16383 bytes • Max. 4 bytes = 256MB
  • 14. MQTT API Flows Most control packets have a corresponding acknowledgment Connect • Can restart a previous session • Can specify a “Last Will and Testament” message and topic Subscribe can specify multiple topics Publish flows • Flow depends on QoS level • Sent from client → server to publish a message, or • Server → client to send messages Connection Management CONNECT CONNACK DISCONNECT PINGREQ PINGRESP Subscription Management SUBSCRIBE SUBACK UNSUBSCRIBE UNSUBACK Message Delivery PUBLISH PUBACK PUBREC PUBREL PUBCOMP
  • 15. Qualities of Service QoS 0: At most once delivery (non-persistent) – No retry semantics are defined in the protocol. – The message arrives either once or not at all. QoS 1: At least once delivery (persistent, duplicates are possible) – Sender sends message with Message ID in the message header – Receiver acknowledges with a PUBACK control packet – Message is resent with DUP bit set if the PUBACK is not received QoS 2: Exactly once delivery (persistent) – Two stage process to ensure that message is not duplicated – Server acknowledges with a PUBREC control packet – Client releases message with a PUBREL control packet – Server acknowledges completion with a PUBCOMP control packet
  • 16. MQTT Topics All subscriptions are to a topic space All messages are published to an individual topic Topic names are hierarchical • Levels separated by “/” • Single-level wildcards “+” can appear anywhere in the topic string • Multi-level wildcards “#” must appear at the end of the string • Wildcards must be next to a separator • Can't use wildcards when publishing MQTT topic names can be 64KB long Fruit Grape Red White Fruit/# Fruit/Grape/+ Fruit/+/Red
  • 17. MQTT Keep Alive Protocol includes support for client and server to detect failed connections • At connection time, a keep alive can be specified If the client does not send a PINGREQ request to the server, the server assumes the connection (or the client) has failed. A client can also use PINGREQ to test the connection to the server. If it does not receive a PINGRESP it can assume that the connection (or server) has failed. The maximum keep alive interval is 18 hours. • Can specify a value of 0 to disable keep alive ??
  • 18. MQTT Last Will & Testament During connection, a Will message and topic can be specified • Abnormal disconnections will cause the server to publish the message • Clean disconnects will not cause the message to publish Can set the message as retained • Message is published to a subscriber when registering Useful to report the connection status of the client • Will message is a retained “down” • Upon connecting, client publishes a retained “up” message.
  • 19. The life of a MQTT client MQTT serverCONNECT SUBACK SUBSCRIBE PINGREQ CONNACK PINGRESP Has a subscriber connected on a topic Is connected, and is awaiting messages Is the connection still active? Yes!
  • 20. The life of a MQTT client (2) MQTT Server PUBLISH PUBLISH PUBREC Send some important messages (QoS 2) Send some low importance messages (QoS 0) PUBREL PUBCOMP DISCONNECTI'm done!
  • 21. Sample MQTT flows - Connection Connect request, specifying 480 second keep alive, and client identifier of “a” • As few as 15 bytes to connect • CONNACK response indicates success/failure 7 6 5 4 3 2 1 0 Fixed Byte 1 0 0 0 1 0 0 0 0 Length (13) 0 0 0 0 1 1 0 1 Protocol Name 0 0 0 0 0 0 0 0 Length (6) 0 0 0 0 0 1 1 0 Name “MQIsdp” Version (3) 0 0 0 0 0 0 1 1 Connect Flags User 0 Pass 0 Will Ret 0 Will QoS 0 0 Will 0 Clean 1 0 Keep Alive 0 0 0 0 0 0 0 1 (480) 1 1 1 0 0 0 0 0 Payload 0x00 0x01 “a”
  • 22. Sample MQTT flows - Publishing Publish flow, with QoS of 1 (at least once) PUBLISH 7 6 5 4 3 2 1 0 Fixed Byte 1 0 0 1 1 (Dup) 0 (QoS) 0 (QoS)1 (Retain) 1 Length (12) 0 0 0 0 1 1 0 0 Topic Name 0 0 0 0 0 0 0 0 (4) 0 0 0 0 0 0 1 1 “temp” Message ID 0 0 0 0 0 0 0 0 (1) 0 0 0 0 0 0 0 1 Payload “105F” PUBACK 7 6 5 4 3 2 1 0 Fixed Byte 1 0 1 0 0 0 0 0 0 Length (2) 0 0 0 0 0 0 1 0 Message ID 0 0 0 0 0 0 0 0 (1) 0 0 0 0 0 0 0 1
  • 23. MQTT 3.1.1 – what is changing? • New protocol name and version number in the CONNECT packet – Indicates that the client wants to use 3.1.1 rather than 3.1 • Client Identifiers are now permitted to have more than 23 characters, and can include Unicode characters • Password field can now be either binary or character based • “Will Message” can now be binary or character • CONNACK now informs the client whether the server was holding state or not • SUBACK can now indicate the failure of a Subscribe request • Standardised the way of carrying MQTT over a Websocket transport • Numerous clarifications, including – Message ordering – Message retry – Unicode characters – Overlapping subscriptions – Error handling and “reserved bits” • More precise language in the specification document itself • Numbered conformance statements • Specification is owned by the OASIS standards development organization
  • 24. Developing with MQTT - What you need: Clients and Servers - Java and JavaScript API walkthrough
  • 25. Commercial • IBM (MQ and MessageSight Appliance) • Software AG (webMethods Nirvana Messaging) • dcSquare (HiveMQ) Open Source or Free download • Mosquitto ( -> Eclipse) • RSMB (IBM developerWorks) • ActiveMQ (Apache) • Apollo (Apache) • Moquette • Mosca (node.js) • RabbitMQ (vmWare) • mqtt.js , eMQTT (GitHub) Web-hosted • Eclipse Paho (implemented using Mosquitto) • Eurotech Everywhere Device Cloud • Litmus Automation Loop • MQTT Servers (information from
  • 26. MQTT Servers from IBM Cloud based server, allows access to a subset of MQTT capabilities IBM Internet of Things Cloud Quickstart MQTT Server Overview IBM MessageSight Hardware Appliance for on-premise / DMZ messaging -Secure (tamper-proof) -Highly Scalable -High availability -Quick and easy to deploy and manage WebSphere MQ Traditional enterprise messaging server, includes optional MQTT feature RSMB / Mosquitto Small footprint MQTT server designed for edge of network / satellite location: -Bridge SAN to WAN -Multiplex multiple devices over single connection to data centre -Autonomous messaging for satellite location -Open source
  • 27. MQTT Clients and APIs Client libraries provide some or all of the following: • Functions to build and parse the MQTT protocol control packets • Threads to handle receipt of incoming control packets • QoS 1 and QoS 2 delivery using a local persistence store • KeepAlive handling • Simple API for developers to use Open Source clients available in Eclipse Paho project • C, C++, Java, JavaScript, Lua, Python and Go Clients for other languages are available, see • E.g. Delphi, Erlang, .Net, Objective-C, PERL, PHP, Ruby • Not all of the client libraries listed on are current. Some are at an early or experimental stage of development, whilst others are stable and mature. You can develop an MQTT client application by programming directly to the MQTT protocol specification, however it is more convenient to use a prebuilt client
  • 28. Eclipse Paho clients • C / C++ – MQTT C Client for Posix and Windows – MQTT C++ Client for Posix and Windows – Embedded MQTT C Client • Java – J2SE client – J2ME client – Android service • Others – JavaScript (for browser and hybrid applications) – Lua – Python – Go
  • 29. Paho C Client libraries • Linux (Posix) or Windows – Full featured clients providing an MQTT api with QoS1, QoS2 and keepAlive handling – Synchronous client (fully synchronous mode) • Connect, Disconnect, Publish, Subscribe and Unsubscribe calls block until they receive a response from the server • Applications use mqtt_receive() to read inbound messages • Client library runs entirely on the calling application’s thread – Synchronous client (asynchronous mode) • Selected by registering a messageReceived, messageDelivered or connectionLost callback. • Library starts a separate thread to handle these callbacks – Asynchronous (use MqttAsynch ) • All API calls are processed asynchronously and invoke a callback when complete • Embedded Client – Limited to the construction and parsing of MQTT control packets – Client runs entirely on the calling application’s thread – Intended for embedded devices that don’t run Linux (e.g. ARM mbed)
  • 30. Eclipse Paho Java APIs for MQTT MqttClient - “Synchronous” or “blocking” API • This was the original API • Some processing is done on background threads, but most calls block until their processing is complete • Slightly simpler to program to than the Asynch API MqttAsyncClient – New “Asynchronous” API • Better fit to asynchronous environments, e.g. Android • All significant processing is done on background threads The synchronous client is actually implemented as a thin layer on top of the Asynchronous one Both interfaces are included in the same Jar file • org.eclipse.paho.client.mqttv3.jar
  • 31. The synchronous Java API MqttClient object is the starting point Incoming messages are received via callbacks Messages can be published synchronously or asynchronously Local persistence stores used to for QoS 1 and 2 • Persistence store implementation can be replaced MqttClient subscribe MqttConnectOptions MqttCallback MqttClientPersistence MqttTopic setCallBack MqttMessage connect getTopic publish publish
  • 32. Synchronous API : Connecting The first step is to create an MqttClient object. This represents the connection of an application to the MQTT server • Specify details of the server (in a URI format), a ClientID and optionally a persistence implementation • The ClientID must be unique for the server that it is connecting to Then specify connection options, and connect. In this example: • Keep alive of 480 seconds • A retained publication Will message of QoS 1
  • 33. Synchronous API : Sending a Message The Message object contains a payload and a few message properties, such as the QoS level. • The payload is always a byte array, though this might be an encoded string Messages can be sent synchronously, using the MqttClient object • This call does not complete until all acknowledgements (if any) have been received: Messages can be sent asynchronously, using an MqttTopic object: Both forms are overloaded so you don't have to create an MqttMessage object first
  • 34. Synchronous API : Subscriptions After connecting, subscribe by providing the topic string: You can subscribe to multiple topics at the same time, and provide QoS levels: Messages will then be delivered to the messageArrived callback Call unsubscribe to stop getting messages. Again, you can optionally provide a list of containing multiple topics:
  • 35. Asynchronous MQTT API This is a completely non-blocking API. You use an MqttAsyncClient object instead of using MqttClient • In this class the methods for connect, disconnect, publish, subscribe and unsubscribe all operate asynchronously • It's quite easy to achieve the effect of a blocking call using the new MqttAsyncClient. We therefore recommend that you use MqttAsyncClient in place of MqttClient You construct the MqttAsyncClient and set callbacks just like you do for the MqttClient:
  • 36. Asynchronous MQTT API MqttAsyncClient provides two asynchronous invocation styles In the first style, each call looks like its MqttClient counterpart except that it returns a token, which you can then use to track completion of the operation: • You can register a listener callback against the token which will get called when the operation completes: • You can block on the token waiting for its completion, which in effect makes the call into a blocking call: In the second style you supply the listener callback as a parameter on the method invocation itself.
  • 37. Asynchronous API: Listener callbacks The ActionListener contains two callback methods, one for Success and one for Failure: Applications may pass application-specific context in the iMqttToken which can then be used by the callback method implementations
  • 38. Receiving messages – both APIs Messages are delivered to the app via a callback mechanism • Callbacks are also used to indicate when the connection has broken, and when an asynchronous publish has has completed Note that the messageArrived callback is scoped to the MqttClient or MqttAsyncClient object and is driven whenever a message arrives on any of its subscriptions.
  • 39. Java api - Further notes To resume a previous session, set the clean session option to false when connecting • You must also use the same client identifier that was used last time If you set cleanSession to true, you still need to provide a clientID, there's a convenience method to generate a random clientID for this case Client-side state is persisted using the initial URI and clientID as its key. • Recent versions of the MQTT Java client can re-connect to a server which has a different URI, using the same client state. This is for HA configurations where you want to failover to a server with a different IP address
  • 40. Internet of Things JavaScript API client = new Messaging.Client(host, port_number, clientid); client.connect({onSuccess:onConnect, keepAliveInterval:0}); function onConnect() { client.subscribe(topic); }; Example code The JavaScript API for MQTT is fully asynchronous. Its functions return their completion status via onSuccess and onFailure callbacks
  • 41. Demo: Internet of Things JavaScript API client = new Messaging.Client("", 16105, "PetersClientId"); client.onConnectionLost = onConnectionLost; client.connect({onSuccess:onConnect, keepAliveInterval:0}); function onConnectionLost(responseObject) { if (responseObject.errorCode !== 0) console.log("onConnectionLost:"+responseObject.errorMessage); else console.log("Disconnected"); }; function onConnect() { console.log("Connected"); }; 1. Example code: Connect to MQTT Server
  • 42. Demo: Internet of Things JavaScript API client = new Messaging.Client("", 16105, “PetersClientId"); client.onConnectionLost = onConnectionLost; client.connect({onSuccess:onConnect, keepAliveInterval:0}); function onConnectionLost(responseObject) { if (responseObject.errorCode !== 0) console.log("onConnectionLost:"+responseObject.errorMessage); else console.log("Disconnected"); }; function onConnect() { console.log("Connected"); }; function onConnect() { // Once a connection has been made, make a subscription to Traffic data console.log("onConnect"); // subscribe to traffic data client.subscribe("demo/cars/CSV/#"); }; client.onMessageArrived = onMessageArrived; function onMessageArrived(message) { console.log("onMessageArrived:"+message.destinationName + " " +message.payloadString); }; 2. Example code: Subscribes and displays messages received
  • 43. MQTT Messaging optimized for mobile, smart sensors and telemetry devices Enables intelligent decision-making based on remote real-world events Management of static or moving assets, people, locations Simple APIs for Java, JavaScript and other languages reduce the burden for application developers An open protocol with Industry leadership & mindshare • MQTT Protocol and client code contributed to open source • see and Eclipse Paho • Open licence allows development communities to provide further client code & device support • 16+ MQTT servers and 40+ MQTT clients • Version 3.1.1 standard currently in OASIS public review process Summary
  • 44. Useful Links MQTT information − MQTT 3.1 Specification − MQTT 3.1.1 Specification − RSMB (server implementation) − Eclipse Paho project − Eclipse M2M Industry Working Group − OASIS MQTT Technical Committee − MQTT: the Smarter Planet Protocol •
  • 45. Questions?
  • 46. We Value Your Feedback Don’t forget to submit your Impact session and speaker feedback! Your feedback is very important to us – we use it to continually improve the conference. Use the Conference Mobile App or the online Agenda Builder to quickly submit your survey • Navigate to “Surveys” to see a view of surveys for sessions you’ve attended 46
  • 47. Thank You
  • 48. Legal Disclaimer • © IBM Corporation 2014. All Rights Reserved. • The information contained in this publication is provided for informational purposes only. While efforts were made to verify the completeness and accuracy of the information contained in this publication, it is provided AS IS without warranty of any kind, express or implied. In addition, this information is based on IBM’s current product plans and strategy, which are subject to change by IBM without notice. IBM shall not be responsible for any damages arising out of the use of, or otherwise related to, this publication or any other materials. Nothing contained in this publication is intended to, nor shall have the effect of, creating any warranties or representations from IBM or its suppliers or licensors, or altering the terms and conditions of the applicable license agreement governing the use of IBM software. • References in this presentation to IBM products, programs, or services do not imply that they will be available in all countries in which IBM operates. Product release dates and/or capabilities referenced in this presentation may change at any time at IBM’s sole discretion based on market opportunities or other factors, and are not intended to be a commitment to future product or feature availability in any way. Nothing contained in these materials is intended to, nor shall have the effect of, stating or implying that any activities undertaken by you will result in any specific sales, revenue growth or other results. • If the text contains performance statistics or references to benchmarks, insert the following language; otherwise delete: Performance is based on measurements and projections using standard IBM benchmarks in a controlled environment. The actual throughput or performance that any user will experience will vary depending upon many factors, including considerations such as the amount of multiprogramming in the user's job stream, the I/O configuration, the storage configuration, and the workload processed. Therefore, no assurance can be given that an individual user will achieve results similar to those stated here. • If the text includes any customer examples, please confirm we have prior written approval from such customer and insert the following language; otherwise delete: All customer examples described are presented as illustrations of how those customers have used IBM products and the results they may have achieved. Actual environmental costs and performance characteristics may vary by customer. • Please review text for proper trademark attribution of IBM products. At first use, each product name must be the full name and include appropriate trademark symbols (e.g., IBM Lotus® Sametime® Unyte™). Subsequent references can drop “IBM” but should include the proper branding (e.g., Lotus Sametime Gateway, or WebSphere Application Server). Please refer to for guidance on which trademarks require the ® or ™ symbol. Do not use abbreviations for IBM product names in your presentation. All product names must be used as adjectives rather than nouns. Please list all of the trademarks that you use in your presentation as follows; delete any not included in your presentation. IBM, the IBM logo, Lotus, Lotus Notes, Notes, Domino, Quickr, Sametime, WebSphere, UC2, PartnerWorld and Lotusphere are trademarks of International Business Machines Corporation in the United States, other countries, or both. Unyte is a trademark of WebDialogs, Inc., in the United States, other countries, or both. • If you reference Adobe® in the text, please mark the first use and include the following; otherwise delete: Adobe, the Adobe logo, PostScript, and the PostScript logo are either registered trademarks or trademarks of Adobe Systems Incorporated in the United States, and/or other countries. • If you reference Java™ in the text, please mark the first use and include the following; otherwise delete: Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both. • If you reference Microsoft® and/or Windows® in the text, please mark the first use and include the following, as applicable; otherwise delete: Microsoft and Windows are trademarks of Microsoft Corporation in the United States, other countries, or both. • If you reference Intel® and/or any of the following Intel products in the text, please mark the first use and include those that you use as follows; otherwise delete: Intel, Intel Centrino, Celeron, Intel Xeon, Intel SpeedStep, Itanium, and Pentium are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States and other countries. • If you reference UNIX® in the text, please mark the first use and include the following; otherwise delete: UNIX is a registered trademark of The Open Group in the United States and other countries. • If you reference Linux® in your presentation, please mark the first use and include the following; otherwise delete: Linux is a registered trademark of Linus Torvalds in the United States, other countries, or both. Other company, product, or service names may be trademarks or service marks of others. • If the text/graphics include screenshots, no actual IBM employee names may be used (even your own), if your screenshots include fictitious company names (e.g., Renovations, Zeta Bank, Acme) please update and insert the following; otherwise delete: All references to [insert fictitious company name] refer to a fictitious company and are used for illustration purposes only.