Untested port of the Ishtar protocol, actually not much of a port since there was really not much to change. http://kisvm2.epfl.ch/record/125676/files/emav08-ishtar-final.pdf

Committer:
ssozonoff
Date:
Thu May 12 08:30:17 2011 +0000
Revision:
0:086ea145b6d7

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ssozonoff 0:086ea145b6d7 1 /*
ssozonoff 0:086ea145b6d7 2 Ishtar Embedded
ssozonoff 0:086ea145b6d7 3 Copyright (C) 2008-2010:
ssozonoff 0:086ea145b6d7 4
ssozonoff 0:086ea145b6d7 5 Alexandre Habersaat <alexandre dot habersaat at gmail dot com>
ssozonoff 0:086ea145b6d7 6 Antoine Beyeler <abeyeler at ab-ware dot com>
ssozonoff 0:086ea145b6d7 7 (http://www.ab-ware.com)
ssozonoff 0:086ea145b6d7 8 Stephane Magnenat <stephane at magnenat dot net>
ssozonoff 0:086ea145b6d7 9 (http://stephane.magnenat.net)
ssozonoff 0:086ea145b6d7 10
ssozonoff 0:086ea145b6d7 11 All rights reserved.
ssozonoff 0:086ea145b6d7 12
ssozonoff 0:086ea145b6d7 13 Ishtar Embedded is free software: you can redistribute it and/or modify
ssozonoff 0:086ea145b6d7 14 it under the terms of the GNU Lesser General Public License as published by
ssozonoff 0:086ea145b6d7 15 the Free Software Foundation, either version 3 of the License, or
ssozonoff 0:086ea145b6d7 16 (at your option) any later version.
ssozonoff 0:086ea145b6d7 17
ssozonoff 0:086ea145b6d7 18 Ishtar Embedded is distributed in the hope that it will be useful,
ssozonoff 0:086ea145b6d7 19 but WITHOUT ANY WARRANTY; without even the implied warranty of
ssozonoff 0:086ea145b6d7 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ssozonoff 0:086ea145b6d7 21 GNU General Public License for more details.
ssozonoff 0:086ea145b6d7 22
ssozonoff 0:086ea145b6d7 23 You should have received a copy of the GNU Lesser General Public License
ssozonoff 0:086ea145b6d7 24 along with Ishtar Embedded. If not, see <http://www.gnu.org/licenses/>.
ssozonoff 0:086ea145b6d7 25 */
ssozonoff 0:086ea145b6d7 26
ssozonoff 0:086ea145b6d7 27 /*!
ssozonoff 0:086ea145b6d7 28 * \file ishtar.c
ssozonoff 0:086ea145b6d7 29 * \brief Main file of the Ishtar Embedded server
ssozonoff 0:086ea145b6d7 30 *
ssozonoff 0:086ea145b6d7 31 * \author Alexandre Habersaat, Antoine Beyeler
ssozonoff 0:086ea145b6d7 32 *
ssozonoff 0:086ea145b6d7 33 * This file contains the core of the Ishtar Embedded server
ssozonoff 0:086ea145b6d7 34 */
ssozonoff 0:086ea145b6d7 35
ssozonoff 0:086ea145b6d7 36 #include "ishtar.h"
ssozonoff 0:086ea145b6d7 37
ssozonoff 0:086ea145b6d7 38 #ifdef __cplusplus
ssozonoff 0:086ea145b6d7 39 extern "C" {
ssozonoff 0:086ea145b6d7 40 #endif
ssozonoff 0:086ea145b6d7 41
ssozonoff 0:086ea145b6d7 42 // Macro for FAR directive
ssozonoff 0:086ea145b6d7 43 #if defined(__dsPIC33F__) || defined(__PIC24F__)
ssozonoff 0:086ea145b6d7 44 #define ISHTAR_ATTRIBUTE_FAR __attribute__((far))
ssozonoff 0:086ea145b6d7 45 #else
ssozonoff 0:086ea145b6d7 46 #define ISHTAR_ATTRIBUTE_FAR
ssozonoff 0:086ea145b6d7 47 #endif
ssozonoff 0:086ea145b6d7 48
ssozonoff 0:086ea145b6d7 49
ssozonoff 0:086ea145b6d7 50 //! The reception buffer of the server
ssozonoff 0:086ea145b6d7 51 unsigned char ishtar_buffer[ISHTAR_BUFFER_SIZE] ISHTAR_ATTRIBUTE_FAR;
ssozonoff 0:086ea145b6d7 52
ssozonoff 0:086ea145b6d7 53 // Statistics
ssozonoff 0:086ea145b6d7 54 //! The number of overflows that occured in the reception buffer
ssozonoff 0:086ea145b6d7 55 unsigned long ishtar_numberOfOverflows = 0;
ssozonoff 0:086ea145b6d7 56 //! The number of bytes dropped in the state Header1
ssozonoff 0:086ea145b6d7 57 unsigned long ishtar_numberOfDropHeader1 = 0;
ssozonoff 0:086ea145b6d7 58 //! The number of bytes dropped in the state Header2
ssozonoff 0:086ea145b6d7 59 unsigned long ishtar_numberOfDropHeader2 = 0;
ssozonoff 0:086ea145b6d7 60 //! The number of bytes dropped in the state Header3
ssozonoff 0:086ea145b6d7 61 unsigned long ishtar_numberOfDropHeader3 = 0;
ssozonoff 0:086ea145b6d7 62 //! The number of bytes dropped in the state Header4
ssozonoff 0:086ea145b6d7 63 unsigned long ishtar_numberOfDropHeader4 = 0;
ssozonoff 0:086ea145b6d7 64 //! The number of messages dropped after a size checksum error
ssozonoff 0:086ea145b6d7 65 unsigned long ishtar_numberOfDropSize = 0;
ssozonoff 0:086ea145b6d7 66 //! The number of messages dropped after a content checksum error
ssozonoff 0:086ea145b6d7 67 unsigned long ishtar_numberOfDropContent = 0;
ssozonoff 0:086ea145b6d7 68 //! The total number of bytes received
ssozonoff 0:086ea145b6d7 69 unsigned long ishtar_numberOfBytesReceived = 0;
ssozonoff 0:086ea145b6d7 70 //! The total number of bytes sent
ssozonoff 0:086ea145b6d7 71 unsigned long ishtar_numberOfBytesSent = 0;
ssozonoff 0:086ea145b6d7 72 //! The total number of bytes read from memory
ssozonoff 0:086ea145b6d7 73 unsigned long ishtar_numberOfBytesReadFromMemory = 0;
ssozonoff 0:086ea145b6d7 74 //! The total number of bytes written to memory
ssozonoff 0:086ea145b6d7 75 unsigned long ishtar_numberOfBytesWrittenToMemory = 0;
ssozonoff 0:086ea145b6d7 76 //! The number of messages that were valid
ssozonoff 0:086ea145b6d7 77 unsigned long ishtar_numberOfValidMessages = 0;
ssozonoff 0:086ea145b6d7 78 //! The number of messages that were valid but contained invalid data (client error or wrong checksum validated)
ssozonoff 0:086ea145b6d7 79 unsigned long ishtar_corruptedValidated = 0;
ssozonoff 0:086ea145b6d7 80 //! The snapshot size
ssozonoff 0:086ea145b6d7 81 unsigned long ishtar_snapshotSize = 0;
ssozonoff 0:086ea145b6d7 82 //! If an error occured with the non-volatile memory
ssozonoff 0:086ea145b6d7 83 unsigned char ishtar_memoryError = NO_ERROR;
ssozonoff 0:086ea145b6d7 84
ssozonoff 0:086ea145b6d7 85 //! The number of services / variables registered
ssozonoff 0:086ea145b6d7 86 ishtar_ServiceId ishtar_numberOfVariables = 0;
ssozonoff 0:086ea145b6d7 87 //! The registry of the services / variables
ssozonoff 0:086ea145b6d7 88 ishtar_ServiceDescription ishtar_services[ISHTAR_MAX_NUMBER_OF_SERVICES] ISHTAR_ATTRIBUTE_FAR;
ssozonoff 0:086ea145b6d7 89
ssozonoff 0:086ea145b6d7 90 //! The Id of the active snapshot (or the last one if none is active)
ssozonoff 0:086ea145b6d7 91 ishtar_RequestId ishtar_snapshotId = 0;
ssozonoff 0:086ea145b6d7 92 //! Snapshot active
ssozonoff 0:086ea145b6d7 93 unsigned char ishtar_snapshotActive = 0;
ssozonoff 0:086ea145b6d7 94
ssozonoff 0:086ea145b6d7 95
ssozonoff 0:086ea145b6d7 96 // read buffer
ssozonoff 0:086ea145b6d7 97 //! The start of the reception buffer
ssozonoff 0:086ea145b6d7 98 unsigned char * ishtar_bufBegin;
ssozonoff 0:086ea145b6d7 99 //! The end of the reception buffer
ssozonoff 0:086ea145b6d7 100 unsigned char * ishtar_bufEnd;
ssozonoff 0:086ea145b6d7 101 //! The position to write in the buffer for the next byte that is received
ssozonoff 0:086ea145b6d7 102 unsigned char * ishtar_bufPos;
ssozonoff 0:086ea145b6d7 103
ssozonoff 0:086ea145b6d7 104 //! The position of the next char to be consumed.
ssozonoff 0:086ea145b6d7 105 unsigned char * ishtar_consumePos;
ssozonoff 0:086ea145b6d7 106 //! Begining of the data payload of the current packet
ssozonoff 0:086ea145b6d7 107 unsigned char* ishtar_dataStartMarker;
ssozonoff 0:086ea145b6d7 108 //! The start of the first packet waiting to be treated in the buffer
ssozonoff 0:086ea145b6d7 109 unsigned char * ishtar_packetBegin = 0;
ssozonoff 0:086ea145b6d7 110
ssozonoff 0:086ea145b6d7 111 //! The state to read the first byte of message header
ssozonoff 0:086ea145b6d7 112 #define ISHTAR_STATE_HEADER1 1
ssozonoff 0:086ea145b6d7 113 //! The state to read the second byte of message header
ssozonoff 0:086ea145b6d7 114 #define ISHTAR_STATE_HEADER2 2
ssozonoff 0:086ea145b6d7 115 //! The state to read the third byte of message header
ssozonoff 0:086ea145b6d7 116 #define ISHTAR_STATE_HEADER3 3
ssozonoff 0:086ea145b6d7 117 //! The state to read the fourth byte of message header
ssozonoff 0:086ea145b6d7 118 #define ISHTAR_STATE_HEADER4 4
ssozonoff 0:086ea145b6d7 119 //! The state to read the size of message
ssozonoff 0:086ea145b6d7 120 #define ISHTAR_STATE_SIZE 5
ssozonoff 0:086ea145b6d7 121 //! The state to read the checksum of the size of the message
ssozonoff 0:086ea145b6d7 122 #define ISHTAR_STATE_CHECKSUM_SIZE 6
ssozonoff 0:086ea145b6d7 123 //! The state to read the content of the message
ssozonoff 0:086ea145b6d7 124 #define ISHTAR_STATE_CONTENT 7
ssozonoff 0:086ea145b6d7 125 //! The state to read the checksum of the content of the message
ssozonoff 0:086ea145b6d7 126 #define ISHTAR_STATE_CHECKSUM_CONTENT 8
ssozonoff 0:086ea145b6d7 127
ssozonoff 0:086ea145b6d7 128 //! The current state of the state machine for reception
ssozonoff 0:086ea145b6d7 129 unsigned char ishtar_state = ISHTAR_STATE_HEADER1;
ssozonoff 0:086ea145b6d7 130 //! Detects overflows in the reception buffer
ssozonoff 0:086ea145b6d7 131 unsigned char ishtar_overFlow = 0;
ssozonoff 0:086ea145b6d7 132 //! The current byte of the size being read
ssozonoff 0:086ea145b6d7 133 unsigned char ishtar_sizeByteNum = 0;
ssozonoff 0:086ea145b6d7 134 //! The current bypte of the checksum being read
ssozonoff 0:086ea145b6d7 135 unsigned char ishtar_checksumByteNum = 0;
ssozonoff 0:086ea145b6d7 136
ssozonoff 0:086ea145b6d7 137 // Checksum read
ssozonoff 0:086ea145b6d7 138 //! The checksum read for the size
ssozonoff 0:086ea145b6d7 139 unsigned short ishtar_sizeChecksumRead = 0;
ssozonoff 0:086ea145b6d7 140 //! The ckecksum read for the content
ssozonoff 0:086ea145b6d7 141 unsigned short ishtar_contentChecksumRead = 0;
ssozonoff 0:086ea145b6d7 142 // Checksum calculated
ssozonoff 0:086ea145b6d7 143 //! Temporary variables to calculate checksums
ssozonoff 0:086ea145b6d7 144 unsigned char ishtar_ckA, ishtar_ckB;
ssozonoff 0:086ea145b6d7 145 //! The total size of the current packet
ssozonoff 0:086ea145b6d7 146 unsigned long ishtar_curPacketSize = 0;
ssozonoff 0:086ea145b6d7 147 //! The number of bytes read for the current packet
ssozonoff 0:086ea145b6d7 148 unsigned long ishtar_curSize = 0;
ssozonoff 0:086ea145b6d7 149
ssozonoff 0:086ea145b6d7 150 //! At least one client is connected to the server
ssozonoff 0:086ea145b6d7 151 unsigned char ishtar_connected = 0;
ssozonoff 0:086ea145b6d7 152
ssozonoff 0:086ea145b6d7 153 // Non-volatile memory access
ssozonoff 0:086ea145b6d7 154 //! The lowest memory address that Ishtar is allowed to read/write
ssozonoff 0:086ea145b6d7 155 unsigned short ishtar_memoryMinAddress = 0;
ssozonoff 0:086ea145b6d7 156 //! The highest memory address that Ishtar is allowed to read/write
ssozonoff 0:086ea145b6d7 157 unsigned short ishtar_memoryMaxAddress = 0;
ssozonoff 0:086ea145b6d7 158 //! The external function to read the non-volatile memory
ssozonoff 0:086ea145b6d7 159 ishtar_MemoryReadFunc ishtar_memoryReadFunc = 0;
ssozonoff 0:086ea145b6d7 160 //! The external function to write the non-volatile memory
ssozonoff 0:086ea145b6d7 161 ishtar_MemoryWriteFunc ishtar_memoryWriteFunc = 0;
ssozonoff 0:086ea145b6d7 162 //! The checksum A for the non-volatile memory consistency
ssozonoff 0:086ea145b6d7 163 unsigned char ishtar_memoryChecksumA = 0;
ssozonoff 0:086ea145b6d7 164 //! The checksum B for the non-volatile memory consistency
ssozonoff 0:086ea145b6d7 165 unsigned char ishtar_memoryChecksumB = 0;
ssozonoff 0:086ea145b6d7 166
ssozonoff 0:086ea145b6d7 167 // Send function
ssozonoff 0:086ea145b6d7 168 //! The external function to call to send data through communication
ssozonoff 0:086ea145b6d7 169 ishtar_ExternalSendFunc ishtar_externalSendFunc;
ssozonoff 0:086ea145b6d7 170 //! The external function to call to send the first heavy messages (blocking function)
ssozonoff 0:086ea145b6d7 171 ishtar_ExternalSendFunc ishtar_externalSendBlockingFunc;
ssozonoff 0:086ea145b6d7 172 //! The current function that is used to send data (blocking or non-blocking)
ssozonoff 0:086ea145b6d7 173 ishtar_ExternalSendFunc ishtar_currentSendFunc;
ssozonoff 0:086ea145b6d7 174 //! The external function to flush the content of the external output buffer (if used)
ssozonoff 0:086ea145b6d7 175 ishtar_ExternalFlushFunc ishtar_externalFlushFunc;
ssozonoff 0:086ea145b6d7 176
ssozonoff 0:086ea145b6d7 177 //! The intermediate function to send data and calculate the checksum of the sent data
ssozonoff 0:086ea145b6d7 178 void ishtar_SendData(unsigned char * data, unsigned long len);
ssozonoff 0:086ea145b6d7 179 //! The function to send the message header
ssozonoff 0:086ea145b6d7 180 void ishtar_SendHeader();
ssozonoff 0:086ea145b6d7 181 //! The function to reset the checksums
ssozonoff 0:086ea145b6d7 182 void ishtar_InitCk();
ssozonoff 0:086ea145b6d7 183 //! The function to send the current checksum of the message
ssozonoff 0:086ea145b6d7 184 void ishtar_SendCk();
ssozonoff 0:086ea145b6d7 185
ssozonoff 0:086ea145b6d7 186 //! An empty function
ssozonoff 0:086ea145b6d7 187 void ishtar_DoNothing() { }
ssozonoff 0:086ea145b6d7 188
ssozonoff 0:086ea145b6d7 189 //! This function inits the pointers to the reception buffer
ssozonoff 0:086ea145b6d7 190 void ishtar_InitBuffer();
ssozonoff 0:086ea145b6d7 191 //! This function is used for debug, to register statistics variables into Ishtar
ssozonoff 0:086ea145b6d7 192 void ishtar_RegisterDebugVars();
ssozonoff 0:086ea145b6d7 193
ssozonoff 0:086ea145b6d7 194 // utils
ssozonoff 0:086ea145b6d7 195 //! This function is used to calculate the checksum of a size
ssozonoff 0:086ea145b6d7 196 unsigned short ishtar_CalculateSizeChecksum(unsigned long size);
ssozonoff 0:086ea145b6d7 197 //! This function normalizes an address (usually old address + offset) to stay inside the reception buffer
ssozonoff 0:086ea145b6d7 198 inline unsigned char * ishtar_WrapAddr(unsigned char * addr);
ssozonoff 0:086ea145b6d7 199 //! This function increments the address of the reception buffer
ssozonoff 0:086ea145b6d7 200 inline void ishtar_IncAddr(unsigned char ** addr, unsigned long size);
ssozonoff 0:086ea145b6d7 201
ssozonoff 0:086ea145b6d7 202 //! This function reads the content of an address and copies it into a variable (target)
ssozonoff 0:086ea145b6d7 203 inline void ishtar_At(unsigned char ** addr, unsigned char * target, unsigned char size);
ssozonoff 0:086ea145b6d7 204 // This function reads the content of an address, copies it into a variable and increment the address to the next position
ssozonoff 0:086ea145b6d7 205 inline void ishtar_AtInc(unsigned char ** addr, unsigned char * target, unsigned char size);
ssozonoff 0:086ea145b6d7 206
ssozonoff 0:086ea145b6d7 207 //! This function sends a zero-terminated string
ssozonoff 0:086ea145b6d7 208 void ishtar_SendString(const char * sz);
ssozonoff 0:086ea145b6d7 209 //! This function sends the value of a variable
ssozonoff 0:086ea145b6d7 210 void ishtar_SendValue(unsigned char * value, ishtar_ValueVectorType type, unsigned long index);
ssozonoff 0:086ea145b6d7 211 //! This function reads a value in a buffer, write it into the registry and increments the read buffer
ssozonoff 0:086ea145b6d7 212 void ishtar_SetValueInc(unsigned char * value, ishtar_ValueVectorType type, unsigned long index, unsigned char ** addr);
ssozonoff 0:086ea145b6d7 213
ssozonoff 0:086ea145b6d7 214 //! This function returns the length of a zero-terminated string or ISHTAR_STRING_MAX_SIZE
ssozonoff 0:086ea145b6d7 215 unsigned long ishtar_Strlen(const char * addr);
ssozonoff 0:086ea145b6d7 216 //! This function returns the size of a type
ssozonoff 0:086ea145b6d7 217 unsigned long ishtar_TypeSize(ishtar_ValueVectorType type);
ssozonoff 0:086ea145b6d7 218
ssozonoff 0:086ea145b6d7 219 // treat messages
ssozonoff 0:086ea145b6d7 220 //! This function decodes the type of a packet and call the corresponding dedicated function
ssozonoff 0:086ea145b6d7 221 void ishtar_HandlePacket(unsigned char * addr, unsigned long len);
ssozonoff 0:086ea145b6d7 222 //! This function decodes the content of a Hello packet and sends the answer
ssozonoff 0:086ea145b6d7 223 void ishtar_HandleHelloCall(unsigned char * addr, unsigned long len);
ssozonoff 0:086ea145b6d7 224 //! This function decodes the content of a GetServiceList packet and sends the answer
ssozonoff 0:086ea145b6d7 225 void ishtar_HandleGetServiceListCall(unsigned char * addr, unsigned long len);
ssozonoff 0:086ea145b6d7 226 //! This function decodes the content of a Get packet and sends the answer. It may also set up a snapshot.
ssozonoff 0:086ea145b6d7 227 void ishtar_HandleGetCall(unsigned char * addr, unsigned long len);
ssozonoff 0:086ea145b6d7 228 //! This function decodes the content of a Set packet and executes the modification on the local service registry
ssozonoff 0:086ea145b6d7 229 void ishtar_HandleSetCall(unsigned char * addr, unsigned long len);
ssozonoff 0:086ea145b6d7 230 //! This function decodes the content of a disconnection packet and stops the snapshot
ssozonoff 0:086ea145b6d7 231 void ishtar_HandleByeByeCall(unsigned char * addr, unsigned long len);
ssozonoff 0:086ea145b6d7 232
ssozonoff 0:086ea145b6d7 233 /*!
ssozonoff 0:086ea145b6d7 234 * This function normalizes an address (usually old address + offset) to stay inside the reception buffer
ssozonoff 0:086ea145b6d7 235 */
ssozonoff 0:086ea145b6d7 236 inline unsigned char * ishtar_WrapAddr(unsigned char * addr)
ssozonoff 0:086ea145b6d7 237 {
ssozonoff 0:086ea145b6d7 238 if (addr >= ishtar_bufEnd)
ssozonoff 0:086ea145b6d7 239 {
ssozonoff 0:086ea145b6d7 240 return (unsigned char*)((unsigned int)ishtar_bufBegin + (unsigned int)addr - (unsigned int)ishtar_bufEnd);
ssozonoff 0:086ea145b6d7 241 }
ssozonoff 0:086ea145b6d7 242 else
ssozonoff 0:086ea145b6d7 243 {
ssozonoff 0:086ea145b6d7 244 return addr;
ssozonoff 0:086ea145b6d7 245 }
ssozonoff 0:086ea145b6d7 246 }
ssozonoff 0:086ea145b6d7 247
ssozonoff 0:086ea145b6d7 248 /*!
ssozonoff 0:086ea145b6d7 249 * This function increments the address of the reception buffer
ssozonoff 0:086ea145b6d7 250 */
ssozonoff 0:086ea145b6d7 251 inline void ishtar_IncAddr(unsigned char ** addr, unsigned long size)
ssozonoff 0:086ea145b6d7 252 {
ssozonoff 0:086ea145b6d7 253 *addr += size;
ssozonoff 0:086ea145b6d7 254 *addr = ishtar_WrapAddr(*addr);
ssozonoff 0:086ea145b6d7 255 }
ssozonoff 0:086ea145b6d7 256
ssozonoff 0:086ea145b6d7 257 /*!
ssozonoff 0:086ea145b6d7 258 * This function reads the content of an address and copies it into a variable (target)
ssozonoff 0:086ea145b6d7 259 */
ssozonoff 0:086ea145b6d7 260 inline void ishtar_At(unsigned char ** addr, unsigned char * target, unsigned char size)
ssozonoff 0:086ea145b6d7 261 {
ssozonoff 0:086ea145b6d7 262 unsigned char i;
ssozonoff 0:086ea145b6d7 263
ssozonoff 0:086ea145b6d7 264 for (i = 0; i < size; ++i)
ssozonoff 0:086ea145b6d7 265 {
ssozonoff 0:086ea145b6d7 266 target[i] = *ishtar_WrapAddr(*addr + i);
ssozonoff 0:086ea145b6d7 267 }
ssozonoff 0:086ea145b6d7 268 }
ssozonoff 0:086ea145b6d7 269
ssozonoff 0:086ea145b6d7 270 /*!
ssozonoff 0:086ea145b6d7 271 * This function reads the content of an address, copies it into a variable and increment the address to the next position
ssozonoff 0:086ea145b6d7 272 */
ssozonoff 0:086ea145b6d7 273 inline void ishtar_AtInc(unsigned char ** addr, unsigned char * target, unsigned char size)
ssozonoff 0:086ea145b6d7 274 {
ssozonoff 0:086ea145b6d7 275 ishtar_At(addr, target, size);
ssozonoff 0:086ea145b6d7 276 ishtar_IncAddr(addr, size);
ssozonoff 0:086ea145b6d7 277 }
ssozonoff 0:086ea145b6d7 278
ssozonoff 0:086ea145b6d7 279
ssozonoff 0:086ea145b6d7 280
ssozonoff 0:086ea145b6d7 281 /*!
ssozonoff 0:086ea145b6d7 282 * This function sends a zero-terminated string
ssozonoff 0:086ea145b6d7 283 */
ssozonoff 0:086ea145b6d7 284 void ishtar_SendString(const char * sz)
ssozonoff 0:086ea145b6d7 285 {
ssozonoff 0:086ea145b6d7 286 // 4 name.type
ssozonoff 0:086ea145b6d7 287 ishtar_ValueVectorSize nameSize;
ssozonoff 0:086ea145b6d7 288 unsigned long j;
ssozonoff 0:086ea145b6d7 289
ssozonoff 0:086ea145b6d7 290 // 4 name.size
ssozonoff 0:086ea145b6d7 291 nameSize = ishtar_Strlen(sz);
ssozonoff 0:086ea145b6d7 292 ishtar_SendData((unsigned char*)(&nameSize), sizeof(ishtar_ValueVectorSize));
ssozonoff 0:086ea145b6d7 293 // X name
ssozonoff 0:086ea145b6d7 294 for (j = 0; j < nameSize; ++j)
ssozonoff 0:086ea145b6d7 295 {
ssozonoff 0:086ea145b6d7 296 ishtar_SendData((unsigned char*)&(sz[j]), 1);
ssozonoff 0:086ea145b6d7 297 }
ssozonoff 0:086ea145b6d7 298 }
ssozonoff 0:086ea145b6d7 299
ssozonoff 0:086ea145b6d7 300 /*!
ssozonoff 0:086ea145b6d7 301 * This function sends the value of an element of a local variable
ssozonoff 0:086ea145b6d7 302 *
ssozonoff 0:086ea145b6d7 303 * @param value The pointer to the variable to read
ssozonoff 0:086ea145b6d7 304 * @param type The type of the variable
ssozonoff 0:086ea145b6d7 305 * @param index The index of the element to read
ssozonoff 0:086ea145b6d7 306 */
ssozonoff 0:086ea145b6d7 307 void ishtar_SendValue(unsigned char * value, ishtar_ValueVectorType type, unsigned long index)
ssozonoff 0:086ea145b6d7 308 {
ssozonoff 0:086ea145b6d7 309 unsigned long size;
ssozonoff 0:086ea145b6d7 310 unsigned char * val;
ssozonoff 0:086ea145b6d7 311
ssozonoff 0:086ea145b6d7 312 size = ishtar_TypeSize(type);
ssozonoff 0:086ea145b6d7 313 val = (unsigned char*) value;
ssozonoff 0:086ea145b6d7 314 ishtar_SendData(&val[size * index], size);
ssozonoff 0:086ea145b6d7 315 }
ssozonoff 0:086ea145b6d7 316
ssozonoff 0:086ea145b6d7 317 /*!
ssozonoff 0:086ea145b6d7 318 * This function modifies the value of one element of a local variable
ssozonoff 0:086ea145b6d7 319 *
ssozonoff 0:086ea145b6d7 320 * @param value The pointer to the variable to set
ssozonoff 0:086ea145b6d7 321 * @param type The type of the variable to set
ssozonoff 0:086ea145b6d7 322 * @param index The index of the element to set (or 0 for a normal variable)
ssozonoff 0:086ea145b6d7 323 * @param addr The address from which to read the value to set
ssozonoff 0:086ea145b6d7 324 */
ssozonoff 0:086ea145b6d7 325 void ishtar_SetValueInc(unsigned char * value, ishtar_ValueVectorType type, unsigned long index, unsigned char ** addr)
ssozonoff 0:086ea145b6d7 326 {
ssozonoff 0:086ea145b6d7 327 unsigned long i;
ssozonoff 0:086ea145b6d7 328 unsigned long size;
ssozonoff 0:086ea145b6d7 329
ssozonoff 0:086ea145b6d7 330 size = ishtar_TypeSize(type);
ssozonoff 0:086ea145b6d7 331
ssozonoff 0:086ea145b6d7 332 for (i = 0; i < size; ++i)
ssozonoff 0:086ea145b6d7 333 {
ssozonoff 0:086ea145b6d7 334 value[size*index+i] = **addr;
ssozonoff 0:086ea145b6d7 335 *addr = ishtar_WrapAddr(*addr + 1);
ssozonoff 0:086ea145b6d7 336 }
ssozonoff 0:086ea145b6d7 337 }
ssozonoff 0:086ea145b6d7 338
ssozonoff 0:086ea145b6d7 339 /*!
ssozonoff 0:086ea145b6d7 340 * This function calculates the checksum of a 4-bytes size
ssozonoff 0:086ea145b6d7 341 *
ssozonoff 0:086ea145b6d7 342 * @return The size on which the checksum is calculated
ssozonoff 0:086ea145b6d7 343 * @return The calculated checksum
ssozonoff 0:086ea145b6d7 344 */
ssozonoff 0:086ea145b6d7 345 unsigned short ishtar_CalculateSizeChecksum(unsigned long size)
ssozonoff 0:086ea145b6d7 346 {
ssozonoff 0:086ea145b6d7 347 unsigned char i;
ssozonoff 0:086ea145b6d7 348 unsigned char * p;
ssozonoff 0:086ea145b6d7 349 unsigned char ckA, ckB;
ssozonoff 0:086ea145b6d7 350
ssozonoff 0:086ea145b6d7 351 ckA = 0;
ssozonoff 0:086ea145b6d7 352 ckB = 0;
ssozonoff 0:086ea145b6d7 353 p = (unsigned char*)(&size);
ssozonoff 0:086ea145b6d7 354 for (i = 0; i < 4; ++i)
ssozonoff 0:086ea145b6d7 355 {
ssozonoff 0:086ea145b6d7 356 ckA += *(p + i);
ssozonoff 0:086ea145b6d7 357 ckB += ckA;
ssozonoff 0:086ea145b6d7 358 }
ssozonoff 0:086ea145b6d7 359
ssozonoff 0:086ea145b6d7 360 return (ckA << 8 | ckB);
ssozonoff 0:086ea145b6d7 361 }
ssozonoff 0:086ea145b6d7 362
ssozonoff 0:086ea145b6d7 363 /*!
ssozonoff 0:086ea145b6d7 364 * This function sends any data. The data sent are added to the current checksums
ssozonoff 0:086ea145b6d7 365 *
ssozonoff 0:086ea145b6d7 366 * @param data A pointer to the data to send
ssozonoff 0:086ea145b6d7 367 * @param len The number of bytes to send from the pointer
ssozonoff 0:086ea145b6d7 368 */
ssozonoff 0:086ea145b6d7 369 void ishtar_SendData(unsigned char * data, unsigned long len)
ssozonoff 0:086ea145b6d7 370 {
ssozonoff 0:086ea145b6d7 371 // Add checksums
ssozonoff 0:086ea145b6d7 372 unsigned long i;
ssozonoff 0:086ea145b6d7 373 for (i = 0; i < len; ++i)
ssozonoff 0:086ea145b6d7 374 {
ssozonoff 0:086ea145b6d7 375 ishtar_ckA += data[i];
ssozonoff 0:086ea145b6d7 376 ishtar_ckB += ishtar_ckA;
ssozonoff 0:086ea145b6d7 377 }
ssozonoff 0:086ea145b6d7 378 // send data
ssozonoff 0:086ea145b6d7 379 ishtar_currentSendFunc(data, len);
ssozonoff 0:086ea145b6d7 380
ssozonoff 0:086ea145b6d7 381 ishtar_numberOfBytesSent += len;
ssozonoff 0:086ea145b6d7 382 }
ssozonoff 0:086ea145b6d7 383
ssozonoff 0:086ea145b6d7 384 /*!
ssozonoff 0:086ea145b6d7 385 * This function sends the Ishtar headers
ssozonoff 0:086ea145b6d7 386 */
ssozonoff 0:086ea145b6d7 387 void ishtar_SendHeader()
ssozonoff 0:086ea145b6d7 388 {
ssozonoff 0:086ea145b6d7 389 // unsigned long header;
ssozonoff 0:086ea145b6d7 390 unsigned char h1, h2, h3, h4;
ssozonoff 0:086ea145b6d7 391 h1 = ISHTAR_HEADER1;
ssozonoff 0:086ea145b6d7 392 h2 = ISHTAR_HEADER2;
ssozonoff 0:086ea145b6d7 393 h3 = ISHTAR_HEADER3;
ssozonoff 0:086ea145b6d7 394 h4 = ISHTAR_HEADER4;
ssozonoff 0:086ea145b6d7 395
ssozonoff 0:086ea145b6d7 396 //header = (ISHTAR_HEADER1) | (ISHTAR_HEADER2 << 8) | (ISHTAR_HEADER3 << 16) | (ISHTAR_HEADER4 << 24);
ssozonoff 0:086ea145b6d7 397 ishtar_currentSendFunc(&h1, 1);
ssozonoff 0:086ea145b6d7 398 ishtar_currentSendFunc(&h2, 1);
ssozonoff 0:086ea145b6d7 399 ishtar_currentSendFunc(&h3, 1);
ssozonoff 0:086ea145b6d7 400 ishtar_currentSendFunc(&h4, 1);
ssozonoff 0:086ea145b6d7 401 }
ssozonoff 0:086ea145b6d7 402
ssozonoff 0:086ea145b6d7 403 /*!
ssozonoff 0:086ea145b6d7 404 * This function resets the current checksum
ssozonoff 0:086ea145b6d7 405 */
ssozonoff 0:086ea145b6d7 406 void ishtar_InitCk()
ssozonoff 0:086ea145b6d7 407 {
ssozonoff 0:086ea145b6d7 408 // initialise checksums to 0
ssozonoff 0:086ea145b6d7 409 ishtar_ckA = 0;
ssozonoff 0:086ea145b6d7 410 ishtar_ckB = 0;
ssozonoff 0:086ea145b6d7 411 }
ssozonoff 0:086ea145b6d7 412
ssozonoff 0:086ea145b6d7 413 /*!
ssozonoff 0:086ea145b6d7 414 * This function sends the current checksum
ssozonoff 0:086ea145b6d7 415 */
ssozonoff 0:086ea145b6d7 416 void ishtar_SendCk()
ssozonoff 0:086ea145b6d7 417 {
ssozonoff 0:086ea145b6d7 418 // compile actual checksums
ssozonoff 0:086ea145b6d7 419 unsigned short checksum;
ssozonoff 0:086ea145b6d7 420 checksum = (ishtar_ckA << 8) | ishtar_ckB;
ssozonoff 0:086ea145b6d7 421
ssozonoff 0:086ea145b6d7 422 // send the compiled checksum
ssozonoff 0:086ea145b6d7 423 ishtar_currentSendFunc((unsigned char*)(&checksum), 2);
ssozonoff 0:086ea145b6d7 424 }
ssozonoff 0:086ea145b6d7 425
ssozonoff 0:086ea145b6d7 426 /*!
ssozonoff 0:086ea145b6d7 427 * This function is provided for convenience if multiple bytes are received at once.
ssozonoff 0:086ea145b6d7 428 * It will call ishtar_ReceiveDataByte() for each of these data bytes
ssozonoff 0:086ea145b6d7 429 */
ssozonoff 0:086ea145b6d7 430 void ishtar_ReceiveData(unsigned char * data, unsigned long len)
ssozonoff 0:086ea145b6d7 431 {
ssozonoff 0:086ea145b6d7 432 unsigned long i;
ssozonoff 0:086ea145b6d7 433 for (i = 0; i < len; ++i)
ssozonoff 0:086ea145b6d7 434 {
ssozonoff 0:086ea145b6d7 435 ishtar_ReceiveDataByte(data[i]);
ssozonoff 0:086ea145b6d7 436 }
ssozonoff 0:086ea145b6d7 437 }
ssozonoff 0:086ea145b6d7 438
ssozonoff 0:086ea145b6d7 439 /*!
ssozonoff 0:086ea145b6d7 440 * This function buffers all incoming bytes without processing them. It drop
ssozonoff 0:086ea145b6d7 441 * any byte in case of buffer overflow.
ssozonoff 0:086ea145b6d7 442 */
ssozonoff 0:086ea145b6d7 443 void ishtar_ReceiveDataByte(unsigned char c)
ssozonoff 0:086ea145b6d7 444 {
ssozonoff 0:086ea145b6d7 445 ++ishtar_numberOfBytesReceived;
ssozonoff 0:086ea145b6d7 446
ssozonoff 0:086ea145b6d7 447 unsigned char* nextAddr = ishtar_WrapAddr(ishtar_bufPos + 1);
ssozonoff 0:086ea145b6d7 448 if (nextAddr == ishtar_packetBegin)
ssozonoff 0:086ea145b6d7 449 {
ssozonoff 0:086ea145b6d7 450 // we have an overflow
ssozonoff 0:086ea145b6d7 451 ishtar_overFlow = 1;
ssozonoff 0:086ea145b6d7 452 ishtar_numberOfOverflows++;
ssozonoff 0:086ea145b6d7 453 }
ssozonoff 0:086ea145b6d7 454 else
ssozonoff 0:086ea145b6d7 455 {
ssozonoff 0:086ea145b6d7 456 *ishtar_bufPos = c;
ssozonoff 0:086ea145b6d7 457 ishtar_bufPos = nextAddr;
ssozonoff 0:086ea145b6d7 458 }
ssozonoff 0:086ea145b6d7 459 }
ssozonoff 0:086ea145b6d7 460
ssozonoff 0:086ea145b6d7 461
ssozonoff 0:086ea145b6d7 462 /*!
ssozonoff 0:086ea145b6d7 463 * This function process bytes from the buffer with a state machine. When a packet
ssozonoff 0:086ea145b6d7 464 * is completed, it calls #ishtar_HandlePacket().
ssozonoff 0:086ea145b6d7 465 *
ssozonoff 0:086ea145b6d7 466 * @param addr The address of the byte to process.
ssozonoff 0:086ea145b6d7 467 */
ssozonoff 0:086ea145b6d7 468 void ishtar_ConsumeBufferedByte(unsigned char* addr)
ssozonoff 0:086ea145b6d7 469 {
ssozonoff 0:086ea145b6d7 470 unsigned char * p;
ssozonoff 0:086ea145b6d7 471 unsigned long i;
ssozonoff 0:086ea145b6d7 472 unsigned char ckA, ckB;
ssozonoff 0:086ea145b6d7 473
ssozonoff 0:086ea145b6d7 474 unsigned char c = *addr;
ssozonoff 0:086ea145b6d7 475
ssozonoff 0:086ea145b6d7 476
ssozonoff 0:086ea145b6d7 477 if (ishtar_state == ISHTAR_STATE_CONTENT)
ssozonoff 0:086ea145b6d7 478 {
ssozonoff 0:086ea145b6d7 479 if (ishtar_curSize == 0)
ssozonoff 0:086ea145b6d7 480 ishtar_dataStartMarker = addr;
ssozonoff 0:086ea145b6d7 481
ssozonoff 0:086ea145b6d7 482 // Increase size
ssozonoff 0:086ea145b6d7 483 ++ishtar_curSize;
ssozonoff 0:086ea145b6d7 484
ssozonoff 0:086ea145b6d7 485 // end of packet
ssozonoff 0:086ea145b6d7 486 if (ishtar_curSize == ishtar_curPacketSize)
ssozonoff 0:086ea145b6d7 487 {
ssozonoff 0:086ea145b6d7 488 ishtar_contentChecksumRead = 0;
ssozonoff 0:086ea145b6d7 489 ishtar_checksumByteNum = 0;
ssozonoff 0:086ea145b6d7 490 ishtar_state = ISHTAR_STATE_CHECKSUM_CONTENT;
ssozonoff 0:086ea145b6d7 491 }
ssozonoff 0:086ea145b6d7 492 }
ssozonoff 0:086ea145b6d7 493 else if (ishtar_state == ISHTAR_STATE_SIZE)
ssozonoff 0:086ea145b6d7 494 {
ssozonoff 0:086ea145b6d7 495 p = (unsigned char*)(&ishtar_curPacketSize);
ssozonoff 0:086ea145b6d7 496 *( p + ishtar_sizeByteNum++ ) = c;
ssozonoff 0:086ea145b6d7 497
ssozonoff 0:086ea145b6d7 498 if (ishtar_sizeByteNum == ISHTAR_NUMBER_OF_SIZE_BYTES)
ssozonoff 0:086ea145b6d7 499 {
ssozonoff 0:086ea145b6d7 500 ishtar_sizeChecksumRead = 0;
ssozonoff 0:086ea145b6d7 501 ishtar_checksumByteNum = 0;
ssozonoff 0:086ea145b6d7 502 ishtar_state = ISHTAR_STATE_CHECKSUM_SIZE;
ssozonoff 0:086ea145b6d7 503 }
ssozonoff 0:086ea145b6d7 504 }
ssozonoff 0:086ea145b6d7 505 else if (ishtar_state == ISHTAR_STATE_HEADER1)
ssozonoff 0:086ea145b6d7 506 {
ssozonoff 0:086ea145b6d7 507 if (c == ISHTAR_HEADER1)
ssozonoff 0:086ea145b6d7 508 ishtar_state = ISHTAR_STATE_HEADER2;
ssozonoff 0:086ea145b6d7 509 else
ssozonoff 0:086ea145b6d7 510 ++ishtar_numberOfDropHeader1;
ssozonoff 0:086ea145b6d7 511 }
ssozonoff 0:086ea145b6d7 512 else if (ishtar_state == ISHTAR_STATE_CHECKSUM_SIZE)
ssozonoff 0:086ea145b6d7 513 {
ssozonoff 0:086ea145b6d7 514 p = (unsigned char*)(&ishtar_sizeChecksumRead);
ssozonoff 0:086ea145b6d7 515 *(p + ishtar_checksumByteNum++) = c;
ssozonoff 0:086ea145b6d7 516
ssozonoff 0:086ea145b6d7 517 if (ishtar_checksumByteNum == ISHTAR_NUMBER_OF_CHECKSUM_BYTES)
ssozonoff 0:086ea145b6d7 518 {
ssozonoff 0:086ea145b6d7 519 p = (unsigned char*)(&ishtar_curPacketSize);
ssozonoff 0:086ea145b6d7 520
ssozonoff 0:086ea145b6d7 521 // calculate checksum of size
ssozonoff 0:086ea145b6d7 522 ckA = 0;
ssozonoff 0:086ea145b6d7 523 ckB = 0;
ssozonoff 0:086ea145b6d7 524 for (i = 0; i < ISHTAR_NUMBER_OF_SIZE_BYTES; ++i)
ssozonoff 0:086ea145b6d7 525 {
ssozonoff 0:086ea145b6d7 526 ckA += (ishtar_curPacketSize >> (8 * i)) & 0xFF;
ssozonoff 0:086ea145b6d7 527 ckB += ckA;
ssozonoff 0:086ea145b6d7 528 }
ssozonoff 0:086ea145b6d7 529
ssozonoff 0:086ea145b6d7 530 if (ishtar_sizeChecksumRead == (ckA << 8 | ckB))
ssozonoff 0:086ea145b6d7 531 {
ssozonoff 0:086ea145b6d7 532 ishtar_curSize = 0;
ssozonoff 0:086ea145b6d7 533 ishtar_state = ISHTAR_STATE_CONTENT;
ssozonoff 0:086ea145b6d7 534 }
ssozonoff 0:086ea145b6d7 535 else
ssozonoff 0:086ea145b6d7 536 {
ssozonoff 0:086ea145b6d7 537 ++ishtar_numberOfDropSize;
ssozonoff 0:086ea145b6d7 538 ishtar_state = ISHTAR_STATE_HEADER1;
ssozonoff 0:086ea145b6d7 539 }
ssozonoff 0:086ea145b6d7 540 }
ssozonoff 0:086ea145b6d7 541 }
ssozonoff 0:086ea145b6d7 542 else if (ishtar_state == ISHTAR_STATE_CHECKSUM_CONTENT)
ssozonoff 0:086ea145b6d7 543 {
ssozonoff 0:086ea145b6d7 544 p = (unsigned char*)(&ishtar_contentChecksumRead);
ssozonoff 0:086ea145b6d7 545 *(p + ishtar_checksumByteNum++) = c;
ssozonoff 0:086ea145b6d7 546
ssozonoff 0:086ea145b6d7 547 if (ishtar_checksumByteNum == ISHTAR_NUMBER_OF_CHECKSUM_BYTES)
ssozonoff 0:086ea145b6d7 548 {
ssozonoff 0:086ea145b6d7 549 // calculate checksum of content, start after the size
ssozonoff 0:086ea145b6d7 550 ckA = 0;
ssozonoff 0:086ea145b6d7 551 ckB = 0;
ssozonoff 0:086ea145b6d7 552 for (i = 0; i < ishtar_curPacketSize; ++i)
ssozonoff 0:086ea145b6d7 553 {
ssozonoff 0:086ea145b6d7 554 ckA += *(ishtar_WrapAddr(ishtar_dataStartMarker + i));
ssozonoff 0:086ea145b6d7 555 ckB += ckA;
ssozonoff 0:086ea145b6d7 556 }
ssozonoff 0:086ea145b6d7 557
ssozonoff 0:086ea145b6d7 558 // checksum correct
ssozonoff 0:086ea145b6d7 559 if (ishtar_contentChecksumRead == (ckA << 8 | ckB))
ssozonoff 0:086ea145b6d7 560 {
ssozonoff 0:086ea145b6d7 561 // handle the packet
ssozonoff 0:086ea145b6d7 562 ishtar_HandlePacket(ishtar_dataStartMarker, ishtar_curPacketSize);
ssozonoff 0:086ea145b6d7 563 ++ishtar_numberOfValidMessages;
ssozonoff 0:086ea145b6d7 564 }
ssozonoff 0:086ea145b6d7 565 else
ssozonoff 0:086ea145b6d7 566 ++ishtar_numberOfDropContent;
ssozonoff 0:086ea145b6d7 567
ssozonoff 0:086ea145b6d7 568 // the begining of the buffer is at the next char in all cases.
ssozonoff 0:086ea145b6d7 569 ishtar_packetBegin = ishtar_WrapAddr(addr + 1);
ssozonoff 0:086ea145b6d7 570
ssozonoff 0:086ea145b6d7 571 // go back for next message
ssozonoff 0:086ea145b6d7 572 ishtar_state = ISHTAR_STATE_HEADER1;
ssozonoff 0:086ea145b6d7 573 }
ssozonoff 0:086ea145b6d7 574 }
ssozonoff 0:086ea145b6d7 575 else if (ishtar_state == ISHTAR_STATE_HEADER2)
ssozonoff 0:086ea145b6d7 576 {
ssozonoff 0:086ea145b6d7 577 if (c == ISHTAR_HEADER2)
ssozonoff 0:086ea145b6d7 578 ishtar_state = ISHTAR_STATE_HEADER3;
ssozonoff 0:086ea145b6d7 579 else if (c == ISHTAR_STATE_HEADER1)
ssozonoff 0:086ea145b6d7 580 {
ssozonoff 0:086ea145b6d7 581 ishtar_state = ISHTAR_STATE_HEADER2;
ssozonoff 0:086ea145b6d7 582 ++ishtar_numberOfDropHeader2;
ssozonoff 0:086ea145b6d7 583 }
ssozonoff 0:086ea145b6d7 584 else
ssozonoff 0:086ea145b6d7 585 {
ssozonoff 0:086ea145b6d7 586 ishtar_state = ISHTAR_STATE_HEADER1;
ssozonoff 0:086ea145b6d7 587 ++ishtar_numberOfDropHeader2;
ssozonoff 0:086ea145b6d7 588 }
ssozonoff 0:086ea145b6d7 589 }
ssozonoff 0:086ea145b6d7 590 else if (ishtar_state == ISHTAR_STATE_HEADER3)
ssozonoff 0:086ea145b6d7 591 {
ssozonoff 0:086ea145b6d7 592 if (c == ISHTAR_HEADER3)
ssozonoff 0:086ea145b6d7 593 ishtar_state = ISHTAR_STATE_HEADER4;
ssozonoff 0:086ea145b6d7 594 else if (c == ISHTAR_STATE_HEADER1)
ssozonoff 0:086ea145b6d7 595 {
ssozonoff 0:086ea145b6d7 596 ishtar_state = ISHTAR_STATE_HEADER2;
ssozonoff 0:086ea145b6d7 597 ++ishtar_numberOfDropHeader3;
ssozonoff 0:086ea145b6d7 598 }
ssozonoff 0:086ea145b6d7 599 else
ssozonoff 0:086ea145b6d7 600 {
ssozonoff 0:086ea145b6d7 601 ishtar_state = ISHTAR_STATE_HEADER1;
ssozonoff 0:086ea145b6d7 602 ++ishtar_numberOfDropHeader3;
ssozonoff 0:086ea145b6d7 603 }
ssozonoff 0:086ea145b6d7 604 }
ssozonoff 0:086ea145b6d7 605 else if (ishtar_state == ISHTAR_STATE_HEADER4)
ssozonoff 0:086ea145b6d7 606 {
ssozonoff 0:086ea145b6d7 607 if (c == ISHTAR_HEADER4)
ssozonoff 0:086ea145b6d7 608 {
ssozonoff 0:086ea145b6d7 609 ishtar_state = ISHTAR_STATE_SIZE;
ssozonoff 0:086ea145b6d7 610 ishtar_curPacketSize = 0;
ssozonoff 0:086ea145b6d7 611 ishtar_sizeByteNum = 0;
ssozonoff 0:086ea145b6d7 612 }
ssozonoff 0:086ea145b6d7 613 else if (c == ISHTAR_STATE_HEADER1)
ssozonoff 0:086ea145b6d7 614 {
ssozonoff 0:086ea145b6d7 615 ishtar_state = ISHTAR_STATE_HEADER2;
ssozonoff 0:086ea145b6d7 616 ++ishtar_numberOfDropHeader4;
ssozonoff 0:086ea145b6d7 617 }
ssozonoff 0:086ea145b6d7 618 else
ssozonoff 0:086ea145b6d7 619 {
ssozonoff 0:086ea145b6d7 620 ishtar_state = ISHTAR_STATE_HEADER1;
ssozonoff 0:086ea145b6d7 621 ++ishtar_numberOfDropHeader4;
ssozonoff 0:086ea145b6d7 622 }
ssozonoff 0:086ea145b6d7 623 }
ssozonoff 0:086ea145b6d7 624 else
ssozonoff 0:086ea145b6d7 625 ishtar_state = ISHTAR_STATE_HEADER1;
ssozonoff 0:086ea145b6d7 626 }
ssozonoff 0:086ea145b6d7 627
ssozonoff 0:086ea145b6d7 628 // step
ssozonoff 0:086ea145b6d7 629
ssozonoff 0:086ea145b6d7 630 /*!
ssozonoff 0:086ea145b6d7 631 * This function checks if there are some packets to treat in the input buffer
ssozonoff 0:086ea145b6d7 632 * If yes, it calls the decoding functions which send the answers to these packets.
ssozonoff 0:086ea145b6d7 633 */
ssozonoff 0:086ea145b6d7 634 void ishtar_Step()
ssozonoff 0:086ea145b6d7 635 {
ssozonoff 0:086ea145b6d7 636 // atomically read the curent bufPos
ssozonoff 0:086ea145b6d7 637 unsigned char* bufPos = ishtar_bufPos;
ssozonoff 0:086ea145b6d7 638
ssozonoff 0:086ea145b6d7 639 while (ishtar_consumePos != bufPos)
ssozonoff 0:086ea145b6d7 640 {
ssozonoff 0:086ea145b6d7 641 ishtar_ConsumeBufferedByte(ishtar_consumePos);
ssozonoff 0:086ea145b6d7 642 ishtar_consumePos = ishtar_WrapAddr(ishtar_consumePos + 1);
ssozonoff 0:086ea145b6d7 643 }
ssozonoff 0:086ea145b6d7 644 }
ssozonoff 0:086ea145b6d7 645
ssozonoff 0:086ea145b6d7 646 /*!
ssozonoff 0:086ea145b6d7 647 * This function reads the start of a packet and determines it type.
ssozonoff 0:086ea145b6d7 648 * It then calls the corresponding dedicated function to decode the packet.
ssozonoff 0:086ea145b6d7 649 */
ssozonoff 0:086ea145b6d7 650 void ishtar_HandlePacket(unsigned char * addr, unsigned long len)
ssozonoff 0:086ea145b6d7 651 {
ssozonoff 0:086ea145b6d7 652 ishtar_MessageId type;
ssozonoff 0:086ea145b6d7 653
ssozonoff 0:086ea145b6d7 654 ishtar_AtInc(&addr, (unsigned char*)&type, sizeof(ishtar_MessageId));
ssozonoff 0:086ea145b6d7 655
ssozonoff 0:086ea145b6d7 656 switch (type)
ssozonoff 0:086ea145b6d7 657 {
ssozonoff 0:086ea145b6d7 658 case HELLO:
ssozonoff 0:086ea145b6d7 659 {
ssozonoff 0:086ea145b6d7 660 ishtar_HandleHelloCall(addr, len - sizeof(ishtar_MessageId));
ssozonoff 0:086ea145b6d7 661 break;
ssozonoff 0:086ea145b6d7 662 }
ssozonoff 0:086ea145b6d7 663 case GET_SERVICE_LIST:
ssozonoff 0:086ea145b6d7 664 {
ssozonoff 0:086ea145b6d7 665 ishtar_HandleGetServiceListCall(addr, len - sizeof(ishtar_MessageId));
ssozonoff 0:086ea145b6d7 666 break;
ssozonoff 0:086ea145b6d7 667 }
ssozonoff 0:086ea145b6d7 668 case GET_VALUES:
ssozonoff 0:086ea145b6d7 669 {
ssozonoff 0:086ea145b6d7 670 ishtar_HandleGetCall(addr, len - sizeof(ishtar_MessageId));
ssozonoff 0:086ea145b6d7 671 break;
ssozonoff 0:086ea145b6d7 672 }
ssozonoff 0:086ea145b6d7 673 case SET_VALUES:
ssozonoff 0:086ea145b6d7 674 {
ssozonoff 0:086ea145b6d7 675 ishtar_HandleSetCall(addr, len - sizeof(ishtar_MessageId));
ssozonoff 0:086ea145b6d7 676 break;
ssozonoff 0:086ea145b6d7 677 }
ssozonoff 0:086ea145b6d7 678 case BYE_BYE:
ssozonoff 0:086ea145b6d7 679 {
ssozonoff 0:086ea145b6d7 680 ishtar_HandleByeByeCall(addr, len - sizeof(ishtar_MessageId));
ssozonoff 0:086ea145b6d7 681 break;
ssozonoff 0:086ea145b6d7 682 }
ssozonoff 0:086ea145b6d7 683 default:
ssozonoff 0:086ea145b6d7 684 {
ssozonoff 0:086ea145b6d7 685 return;
ssozonoff 0:086ea145b6d7 686 }
ssozonoff 0:086ea145b6d7 687 }
ssozonoff 0:086ea145b6d7 688 }
ssozonoff 0:086ea145b6d7 689
ssozonoff 0:086ea145b6d7 690 /*!
ssozonoff 0:086ea145b6d7 691 * This function decodes the Hello calls and sends the Hello answer
ssozonoff 0:086ea145b6d7 692 */
ssozonoff 0:086ea145b6d7 693 void ishtar_HandleHelloCall(unsigned char * addr, unsigned long len)
ssozonoff 0:086ea145b6d7 694 {
ssozonoff 0:086ea145b6d7 695
ssozonoff 0:086ea145b6d7 696 // Stop snapshot when hello received
ssozonoff 0:086ea145b6d7 697 ishtar_snapshotActive = 0;
ssozonoff 0:086ea145b6d7 698
ssozonoff 0:086ea145b6d7 699 ishtar_NodeType nodeType;
ssozonoff 0:086ea145b6d7 700 ishtar_VersionType version;
ssozonoff 0:086ea145b6d7 701
ssozonoff 0:086ea145b6d7 702 ishtar_MessageId hello = HELLO;
ssozonoff 0:086ea145b6d7 703 ishtar_ProtocolType protocol;
ssozonoff 0:086ea145b6d7 704
ssozonoff 0:086ea145b6d7 705 unsigned long answerSize;
ssozonoff 0:086ea145b6d7 706 unsigned short sizeChecksum;
ssozonoff 0:086ea145b6d7 707
ssozonoff 0:086ea145b6d7 708 // READ
ssozonoff 0:086ea145b6d7 709 ishtar_AtInc(&addr, (unsigned char*)&nodeType, sizeof(ishtar_NodeType));
ssozonoff 0:086ea145b6d7 710 ishtar_AtInc(&addr, (unsigned char*)&version, sizeof(ishtar_VersionType));
ssozonoff 0:086ea145b6d7 711
ssozonoff 0:086ea145b6d7 712 // CALCULATE
ssozonoff 0:086ea145b6d7 713 if (version == ISHTAR_PROTOCOL_VERSION)
ssozonoff 0:086ea145b6d7 714 protocol = EMBEDDED;
ssozonoff 0:086ea145b6d7 715 else
ssozonoff 0:086ea145b6d7 716 protocol = INCOMPATIBLE;
ssozonoff 0:086ea145b6d7 717
ssozonoff 0:086ea145b6d7 718 // SEND
ssozonoff 0:086ea145b6d7 719 answerSize = sizeof(ishtar_MessageId) + sizeof(ishtar_ProtocolType);
ssozonoff 0:086ea145b6d7 720 sizeChecksum = ishtar_CalculateSizeChecksum(answerSize);
ssozonoff 0:086ea145b6d7 721
ssozonoff 0:086ea145b6d7 722 ishtar_currentSendFunc = ishtar_externalSendBlockingFunc;
ssozonoff 0:086ea145b6d7 723 ishtar_SendHeader();
ssozonoff 0:086ea145b6d7 724 // send size and size checksum
ssozonoff 0:086ea145b6d7 725 ishtar_SendData((unsigned char*)(&answerSize), sizeof(unsigned long));
ssozonoff 0:086ea145b6d7 726 ishtar_SendData((unsigned char*)(&sizeChecksum), sizeof(unsigned short));
ssozonoff 0:086ea145b6d7 727 // send content
ssozonoff 0:086ea145b6d7 728 ishtar_InitCk();
ssozonoff 0:086ea145b6d7 729 ishtar_SendData((unsigned char*)(&hello), sizeof(ishtar_MessageId));
ssozonoff 0:086ea145b6d7 730 ishtar_SendData((unsigned char*)(&protocol), sizeof(ishtar_ProtocolType));
ssozonoff 0:086ea145b6d7 731 ishtar_SendCk();
ssozonoff 0:086ea145b6d7 732
ssozonoff 0:086ea145b6d7 733 ishtar_externalFlushFunc();
ssozonoff 0:086ea145b6d7 734 ishtar_currentSendFunc = ishtar_externalSendFunc;
ssozonoff 0:086ea145b6d7 735
ssozonoff 0:086ea145b6d7 736 ishtar_connected = 1;
ssozonoff 0:086ea145b6d7 737 }
ssozonoff 0:086ea145b6d7 738
ssozonoff 0:086ea145b6d7 739 /*!
ssozonoff 0:086ea145b6d7 740 * This function decodes the ServiceList calls and sends the list of all registered variables
ssozonoff 0:086ea145b6d7 741 */
ssozonoff 0:086ea145b6d7 742 void ishtar_HandleGetServiceListCall(unsigned char * addr, unsigned long len)
ssozonoff 0:086ea145b6d7 743 {
ssozonoff 0:086ea145b6d7 744 // Nothing to read
ssozonoff 0:086ea145b6d7 745 // Calculate size
ssozonoff 0:086ea145b6d7 746 unsigned long answerSize; // AnswerType + numberOfVariables
ssozonoff 0:086ea145b6d7 747 ishtar_ServiceId i;
ssozonoff 0:086ea145b6d7 748
ssozonoff 0:086ea145b6d7 749 ishtar_MessageId serviceList;
ssozonoff 0:086ea145b6d7 750 unsigned short sizeChecksum;
ssozonoff 0:086ea145b6d7 751
ssozonoff 0:086ea145b6d7 752 // READ - nothing
ssozonoff 0:086ea145b6d7 753
ssozonoff 0:086ea145b6d7 754 // SEND
ssozonoff 0:086ea145b6d7 755 answerSize = sizeof(ishtar_MessageId) + sizeof(ishtar_ServiceId);
ssozonoff 0:086ea145b6d7 756 serviceList = SERVICE_LIST;
ssozonoff 0:086ea145b6d7 757 // ID (4) + name.size(4) + name(X) + type(4) + flags(4) + length(4)
ssozonoff 0:086ea145b6d7 758 // Must be in a for loop as the name of services have different sizes
ssozonoff 0:086ea145b6d7 759 for (i = 0; i < ishtar_numberOfVariables; ++i)
ssozonoff 0:086ea145b6d7 760 {
ssozonoff 0:086ea145b6d7 761 answerSize += sizeof(ishtar_ServiceId) + sizeof(ishtar_ValueVectorSize) + ishtar_Strlen(ishtar_services[i].name) + sizeof(ishtar_ValueVectorType) + sizeof(ishtar_ServiceFlags) + sizeof(ishtar_ValueVectorSize);
ssozonoff 0:086ea145b6d7 762 }
ssozonoff 0:086ea145b6d7 763
ssozonoff 0:086ea145b6d7 764 // calculate size checksum
ssozonoff 0:086ea145b6d7 765 sizeChecksum = ishtar_CalculateSizeChecksum(answerSize);
ssozonoff 0:086ea145b6d7 766
ssozonoff 0:086ea145b6d7 767 ishtar_currentSendFunc = ishtar_externalSendBlockingFunc;
ssozonoff 0:086ea145b6d7 768 ishtar_SendHeader();
ssozonoff 0:086ea145b6d7 769 // send size and size checksum
ssozonoff 0:086ea145b6d7 770 ishtar_SendData((unsigned char*)(&answerSize), sizeof(unsigned long));
ssozonoff 0:086ea145b6d7 771 ishtar_SendData((unsigned char*)(&sizeChecksum), sizeof(unsigned short));
ssozonoff 0:086ea145b6d7 772
ssozonoff 0:086ea145b6d7 773 // send content
ssozonoff 0:086ea145b6d7 774 ishtar_InitCk();
ssozonoff 0:086ea145b6d7 775 ishtar_SendData((unsigned char*)(&serviceList), sizeof(ishtar_MessageId));
ssozonoff 0:086ea145b6d7 776 ishtar_SendData((unsigned char*)(&ishtar_numberOfVariables), sizeof(ishtar_ServiceId));
ssozonoff 0:086ea145b6d7 777
ssozonoff 0:086ea145b6d7 778 // fill table
ssozonoff 0:086ea145b6d7 779 for (i = 0; i < ishtar_numberOfVariables; ++i)
ssozonoff 0:086ea145b6d7 780 {
ssozonoff 0:086ea145b6d7 781 // 4 service id
ssozonoff 0:086ea145b6d7 782 ishtar_SendData((unsigned char*)(&i), sizeof(ishtar_ServiceId));
ssozonoff 0:086ea145b6d7 783 // name.size(4) + name(X)
ssozonoff 0:086ea145b6d7 784 ishtar_SendString(ishtar_services[i].name);
ssozonoff 0:086ea145b6d7 785 // 4 service.type
ssozonoff 0:086ea145b6d7 786 ishtar_SendData((unsigned char*)(&(ishtar_services[i].type)), sizeof(ishtar_ValueVectorType));
ssozonoff 0:086ea145b6d7 787 // 4 service.flags
ssozonoff 0:086ea145b6d7 788 ishtar_SendData((unsigned char*)(&(ishtar_services[i].flags)), sizeof(ishtar_ServiceFlags));
ssozonoff 0:086ea145b6d7 789 // 4 service.length
ssozonoff 0:086ea145b6d7 790 ishtar_SendData((unsigned char*)(&(ishtar_services[i].length)), sizeof(ishtar_ValueVectorSize));
ssozonoff 0:086ea145b6d7 791 }
ssozonoff 0:086ea145b6d7 792
ssozonoff 0:086ea145b6d7 793 ishtar_SendCk();
ssozonoff 0:086ea145b6d7 794
ssozonoff 0:086ea145b6d7 795 ishtar_externalFlushFunc();
ssozonoff 0:086ea145b6d7 796 ishtar_currentSendFunc = ishtar_externalSendFunc;
ssozonoff 0:086ea145b6d7 797 }
ssozonoff 0:086ea145b6d7 798
ssozonoff 0:086ea145b6d7 799 /*!
ssozonoff 0:086ea145b6d7 800 * This function decodes the Get calls and sends the values for the requested data
ssozonoff 0:086ea145b6d7 801 */
ssozonoff 0:086ea145b6d7 802 void ishtar_HandleGetCall(unsigned char * addr, unsigned long len)
ssozonoff 0:086ea145b6d7 803 {
ssozonoff 0:086ea145b6d7 804 // Read
ssozonoff 0:086ea145b6d7 805 ishtar_RequestId requestID;
ssozonoff 0:086ea145b6d7 806 ishtar_ServiceId numberOfIds;
ssozonoff 0:086ea145b6d7 807 ishtar_ValueVectorSize numberOfIndices;
ssozonoff 0:086ea145b6d7 808
ssozonoff 0:086ea145b6d7 809
ssozonoff 0:086ea145b6d7 810 unsigned long answerSize;// VALUES(4) + requestID(4) + size(4)
ssozonoff 0:086ea145b6d7 811 unsigned short sizeChecksum;
ssozonoff 0:086ea145b6d7 812 ishtar_ServiceId i;
ssozonoff 0:086ea145b6d7 813 ishtar_ValueVectorSize j;
ssozonoff 0:086ea145b6d7 814
ssozonoff 0:086ea145b6d7 815 ishtar_ServiceId id;
ssozonoff 0:086ea145b6d7 816 ishtar_ValueVectorSize indice;
ssozonoff 0:086ea145b6d7 817 ishtar_ValueVectorSize length;
ssozonoff 0:086ea145b6d7 818 unsigned char snapshot = 0;
ssozonoff 0:086ea145b6d7 819 ishtar_MessageId values;
ssozonoff 0:086ea145b6d7 820 unsigned char * ids;
ssozonoff 0:086ea145b6d7 821
ssozonoff 0:086ea145b6d7 822 // READ
ssozonoff 0:086ea145b6d7 823 ishtar_AtInc(&addr,(unsigned char*)&requestID, sizeof(ishtar_RequestId));
ssozonoff 0:086ea145b6d7 824 ishtar_AtInc(&addr,(unsigned char*)&snapshot, sizeof(unsigned char));
ssozonoff 0:086ea145b6d7 825 ishtar_AtInc(&addr,(unsigned char*)&numberOfIds, sizeof(ishtar_ServiceId));
ssozonoff 0:086ea145b6d7 826
ssozonoff 0:086ea145b6d7 827 if (snapshot)
ssozonoff 0:086ea145b6d7 828 {
ssozonoff 0:086ea145b6d7 829 // saves the snapshot id
ssozonoff 0:086ea145b6d7 830 ishtar_snapshotId = requestID;
ssozonoff 0:086ea145b6d7 831 // snapshot canceled
ssozonoff 0:086ea145b6d7 832 if (numberOfIds == 0)
ssozonoff 0:086ea145b6d7 833 {
ssozonoff 0:086ea145b6d7 834 ishtar_snapshotActive = 0;
ssozonoff 0:086ea145b6d7 835 }
ssozonoff 0:086ea145b6d7 836 // new snapshot asked
ssozonoff 0:086ea145b6d7 837 else
ssozonoff 0:086ea145b6d7 838 {
ssozonoff 0:086ea145b6d7 839 ishtar_snapshotActive = 1;
ssozonoff 0:086ea145b6d7 840 }
ssozonoff 0:086ea145b6d7 841
ssozonoff 0:086ea145b6d7 842 // clear old snapshot
ssozonoff 0:086ea145b6d7 843 for (i = 0; i < ishtar_numberOfVariables; ++i)
ssozonoff 0:086ea145b6d7 844 {
ssozonoff 0:086ea145b6d7 845 ishtar_services[i].inSnapshot = 0;
ssozonoff 0:086ea145b6d7 846 }
ssozonoff 0:086ea145b6d7 847 }
ssozonoff 0:086ea145b6d7 848
ssozonoff 0:086ea145b6d7 849 ids = addr;
ssozonoff 0:086ea145b6d7 850
ssozonoff 0:086ea145b6d7 851 // Size
ssozonoff 0:086ea145b6d7 852 answerSize = sizeof(ishtar_MessageId) + sizeof(ishtar_RequestId);
ssozonoff 0:086ea145b6d7 853
ssozonoff 0:086ea145b6d7 854 values = VALUES;
ssozonoff 0:086ea145b6d7 855
ssozonoff 0:086ea145b6d7 856 for (i = 0; i<numberOfIds; ++i)
ssozonoff 0:086ea145b6d7 857 {
ssozonoff 0:086ea145b6d7 858 // read id of service
ssozonoff 0:086ea145b6d7 859 ishtar_AtInc(&addr,(unsigned char*)&id, sizeof(ishtar_ServiceId));
ssozonoff 0:086ea145b6d7 860
ssozonoff 0:086ea145b6d7 861 // Problem, a corrupted message has been validated
ssozonoff 0:086ea145b6d7 862 if ( id >= ishtar_numberOfVariables)
ssozonoff 0:086ea145b6d7 863 {
ssozonoff 0:086ea145b6d7 864 ++ishtar_corruptedValidated;
ssozonoff 0:086ea145b6d7 865 return;
ssozonoff 0:086ea145b6d7 866 }
ssozonoff 0:086ea145b6d7 867
ssozonoff 0:086ea145b6d7 868 // if the variable is in the snapshot
ssozonoff 0:086ea145b6d7 869 if (snapshot)
ssozonoff 0:086ea145b6d7 870 {
ssozonoff 0:086ea145b6d7 871 ishtar_services[id].inSnapshot = 1;
ssozonoff 0:086ea145b6d7 872 }
ssozonoff 0:086ea145b6d7 873
ssozonoff 0:086ea145b6d7 874 // Read the number of indices
ssozonoff 0:086ea145b6d7 875 ishtar_AtInc(&addr,(unsigned char*)&numberOfIndices, sizeof(ishtar_ValueVectorSize));
ssozonoff 0:086ea145b6d7 876 // Eat these indices, so that the next variable id is correct
ssozonoff 0:086ea145b6d7 877 for (j = 0; j < numberOfIndices; ++j)
ssozonoff 0:086ea145b6d7 878 {
ssozonoff 0:086ea145b6d7 879 ishtar_AtInc(&addr,(unsigned char*)&indice, sizeof(ishtar_ValueVectorSize));
ssozonoff 0:086ea145b6d7 880 // Problem, a corrupter message has been validated
ssozonoff 0:086ea145b6d7 881 if (indice > ishtar_services[id].length)
ssozonoff 0:086ea145b6d7 882 {
ssozonoff 0:086ea145b6d7 883 ++ishtar_corruptedValidated;
ssozonoff 0:086ea145b6d7 884 return;
ssozonoff 0:086ea145b6d7 885 }
ssozonoff 0:086ea145b6d7 886 }
ssozonoff 0:086ea145b6d7 887
ssozonoff 0:086ea145b6d7 888 // if the size is 0, it means variable size, so we must specify it.
ssozonoff 0:086ea145b6d7 889 if (ishtar_services[id].length == 0 && ishtar_services[id].type == UCHAR)
ssozonoff 0:086ea145b6d7 890 {
ssozonoff 0:086ea145b6d7 891 answerSize += sizeof(ishtar_ValueVectorSize);// size of the size
ssozonoff 0:086ea145b6d7 892 answerSize += ishtar_Strlen((char*)(ishtar_services[id].value)); // size of the data
ssozonoff 0:086ea145b6d7 893 }
ssozonoff 0:086ea145b6d7 894 else
ssozonoff 0:086ea145b6d7 895 {
ssozonoff 0:086ea145b6d7 896 // we only put the data in the next message
ssozonoff 0:086ea145b6d7 897 // here the full variable
ssozonoff 0:086ea145b6d7 898 if (numberOfIndices == 0)
ssozonoff 0:086ea145b6d7 899 {
ssozonoff 0:086ea145b6d7 900 answerSize += ((unsigned long)(ishtar_services[id].length)) * ishtar_TypeSize(ishtar_services[id].type);
ssozonoff 0:086ea145b6d7 901 }
ssozonoff 0:086ea145b6d7 902 // here only some values
ssozonoff 0:086ea145b6d7 903 else
ssozonoff 0:086ea145b6d7 904 {
ssozonoff 0:086ea145b6d7 905 answerSize += ((unsigned long)(numberOfIndices)) * ishtar_TypeSize(ishtar_services[id].type);
ssozonoff 0:086ea145b6d7 906 }
ssozonoff 0:086ea145b6d7 907 }
ssozonoff 0:086ea145b6d7 908 }
ssozonoff 0:086ea145b6d7 909
ssozonoff 0:086ea145b6d7 910 // answer only if non-snapshot, otherwise it will be done in ishtar_Snapshot()
ssozonoff 0:086ea145b6d7 911 if (!snapshot)
ssozonoff 0:086ea145b6d7 912 {
ssozonoff 0:086ea145b6d7 913 sizeChecksum = ishtar_CalculateSizeChecksum(answerSize);
ssozonoff 0:086ea145b6d7 914
ssozonoff 0:086ea145b6d7 915 // SEND
ssozonoff 0:086ea145b6d7 916 ishtar_SendHeader();
ssozonoff 0:086ea145b6d7 917 // send size and size checksum
ssozonoff 0:086ea145b6d7 918 ishtar_SendData((unsigned char*)(&answerSize), 4);
ssozonoff 0:086ea145b6d7 919 ishtar_SendData((unsigned char*)(&sizeChecksum), 2);
ssozonoff 0:086ea145b6d7 920
ssozonoff 0:086ea145b6d7 921 // send content
ssozonoff 0:086ea145b6d7 922 ishtar_InitCk();
ssozonoff 0:086ea145b6d7 923 ishtar_SendData((unsigned char*)(&values), sizeof(ishtar_MessageId));
ssozonoff 0:086ea145b6d7 924 ishtar_SendData((unsigned char*)(&requestID), sizeof(ishtar_RequestId));
ssozonoff 0:086ea145b6d7 925
ssozonoff 0:086ea145b6d7 926 for (i = 0; i < numberOfIds; ++i)
ssozonoff 0:086ea145b6d7 927 {
ssozonoff 0:086ea145b6d7 928 // service id
ssozonoff 0:086ea145b6d7 929 ishtar_AtInc(&ids, (unsigned char*)&id, sizeof(ishtar_ServiceId));
ssozonoff 0:086ea145b6d7 930 // number of indices
ssozonoff 0:086ea145b6d7 931 ishtar_AtInc(&ids,(unsigned char*)&numberOfIndices, sizeof(ishtar_ValueVectorSize));
ssozonoff 0:086ea145b6d7 932
ssozonoff 0:086ea145b6d7 933 // length == 0 mean variable size, ONLY for char or UCHAR, with ended caracter equal to '\0'
ssozonoff 0:086ea145b6d7 934 if (ishtar_services[id].type == UCHAR && ishtar_services[id].length == 0)
ssozonoff 0:086ea145b6d7 935 {
ssozonoff 0:086ea145b6d7 936 length = ishtar_Strlen((char*)(ishtar_services[id].value));
ssozonoff 0:086ea145b6d7 937 ishtar_SendData((unsigned char*)(&length), sizeof(ishtar_ValueVectorSize));
ssozonoff 0:086ea145b6d7 938
ssozonoff 0:086ea145b6d7 939 for (j = 0; j < length; ++j)
ssozonoff 0:086ea145b6d7 940 {
ssozonoff 0:086ea145b6d7 941 ishtar_SendValue((unsigned char*)ishtar_services[id].value, ishtar_services[id].type, j);
ssozonoff 0:086ea145b6d7 942 }
ssozonoff 0:086ea145b6d7 943
ssozonoff 0:086ea145b6d7 944 }
ssozonoff 0:086ea145b6d7 945 else
ssozonoff 0:086ea145b6d7 946 {
ssozonoff 0:086ea145b6d7 947 // read the indices
ssozonoff 0:086ea145b6d7 948 if (numberOfIndices > 0)
ssozonoff 0:086ea145b6d7 949 {
ssozonoff 0:086ea145b6d7 950 for (j = 0; j < numberOfIndices; ++j)
ssozonoff 0:086ea145b6d7 951 {
ssozonoff 0:086ea145b6d7 952 ishtar_AtInc(&ids,(unsigned char*)&indice, sizeof(ishtar_ValueVectorSize));
ssozonoff 0:086ea145b6d7 953 ishtar_SendValue((unsigned char*)ishtar_services[id].value, ishtar_services[id].type, indice);
ssozonoff 0:086ea145b6d7 954
ssozonoff 0:086ea145b6d7 955 }
ssozonoff 0:086ea145b6d7 956 }
ssozonoff 0:086ea145b6d7 957 else
ssozonoff 0:086ea145b6d7 958 {
ssozonoff 0:086ea145b6d7 959 for (j = 0; j < ishtar_services[id].length; ++j)
ssozonoff 0:086ea145b6d7 960 {
ssozonoff 0:086ea145b6d7 961
ssozonoff 0:086ea145b6d7 962 ishtar_SendValue((unsigned char*)ishtar_services[id].value, ishtar_services[id].type, j);
ssozonoff 0:086ea145b6d7 963 }
ssozonoff 0:086ea145b6d7 964 }
ssozonoff 0:086ea145b6d7 965 }
ssozonoff 0:086ea145b6d7 966 }
ssozonoff 0:086ea145b6d7 967
ssozonoff 0:086ea145b6d7 968 ishtar_SendCk();
ssozonoff 0:086ea145b6d7 969 ishtar_externalFlushFunc();
ssozonoff 0:086ea145b6d7 970 }
ssozonoff 0:086ea145b6d7 971 }
ssozonoff 0:086ea145b6d7 972
ssozonoff 0:086ea145b6d7 973 /*!
ssozonoff 0:086ea145b6d7 974 * This function decodes the Set calls and updates local variables
ssozonoff 0:086ea145b6d7 975 */
ssozonoff 0:086ea145b6d7 976 void ishtar_HandleSetCall(unsigned char * addr, unsigned long len)
ssozonoff 0:086ea145b6d7 977 {
ssozonoff 0:086ea145b6d7 978 ishtar_RequestId requestID;
ssozonoff 0:086ea145b6d7 979 unsigned char feedback;
ssozonoff 0:086ea145b6d7 980 ishtar_ServiceId numberOfIds;
ssozonoff 0:086ea145b6d7 981 ishtar_ValueVectorSize numberOfIndices;
ssozonoff 0:086ea145b6d7 982 ishtar_ServiceId i;
ssozonoff 0:086ea145b6d7 983 ishtar_ValueVectorSize j;
ssozonoff 0:086ea145b6d7 984 ishtar_ServiceId id;
ssozonoff 0:086ea145b6d7 985 ishtar_ValueVectorSize indice;
ssozonoff 0:086ea145b6d7 986 unsigned char * indicesAddr;
ssozonoff 0:086ea145b6d7 987
ssozonoff 0:086ea145b6d7 988 unsigned long answerSize;
ssozonoff 0:086ea145b6d7 989 unsigned short sizeChecksum;
ssozonoff 0:086ea145b6d7 990 ishtar_MessageId setAck;
ssozonoff 0:086ea145b6d7 991
ssozonoff 0:086ea145b6d7 992
ssozonoff 0:086ea145b6d7 993 // READ
ssozonoff 0:086ea145b6d7 994 // request id
ssozonoff 0:086ea145b6d7 995 ishtar_AtInc(&addr, (unsigned char*)&requestID, sizeof(ishtar_RequestId));
ssozonoff 0:086ea145b6d7 996 // feedback
ssozonoff 0:086ea145b6d7 997 ishtar_AtInc(&addr, (unsigned char*)&feedback, 1);
ssozonoff 0:086ea145b6d7 998 //numberOfIds
ssozonoff 0:086ea145b6d7 999 ishtar_AtInc(&addr, (unsigned char*)&numberOfIds, sizeof(ishtar_ServiceId));
ssozonoff 0:086ea145b6d7 1000
ssozonoff 0:086ea145b6d7 1001 for (i = 0; i < numberOfIds; ++i)
ssozonoff 0:086ea145b6d7 1002 {
ssozonoff 0:086ea145b6d7 1003 //id = ishtar_ulongAtInc(&addr);
ssozonoff 0:086ea145b6d7 1004 ishtar_AtInc(&addr, (unsigned char*)&id, sizeof(ishtar_ServiceId));
ssozonoff 0:086ea145b6d7 1005
ssozonoff 0:086ea145b6d7 1006 // Problem, a corrupted message has been validated
ssozonoff 0:086ea145b6d7 1007 if (id > ishtar_numberOfVariables)
ssozonoff 0:086ea145b6d7 1008 {
ssozonoff 0:086ea145b6d7 1009 ++ishtar_corruptedValidated;
ssozonoff 0:086ea145b6d7 1010 return;
ssozonoff 0:086ea145b6d7 1011 }
ssozonoff 0:086ea145b6d7 1012
ssozonoff 0:086ea145b6d7 1013 // number of indices
ssozonoff 0:086ea145b6d7 1014 ishtar_AtInc(&addr, (unsigned char*)&numberOfIndices, sizeof(ishtar_ValueVectorSize));
ssozonoff 0:086ea145b6d7 1015 indicesAddr = addr;
ssozonoff 0:086ea145b6d7 1016
ssozonoff 0:086ea145b6d7 1017 // readonly, so skip
ssozonoff 0:086ea145b6d7 1018 if (ishtar_services[id].flags & READ_ONLY)
ssozonoff 0:086ea145b6d7 1019 {
ssozonoff 0:086ea145b6d7 1020 if (numberOfIndices == 0)
ssozonoff 0:086ea145b6d7 1021 {
ssozonoff 0:086ea145b6d7 1022 // skip
ssozonoff 0:086ea145b6d7 1023 ishtar_IncAddr(&addr, ishtar_TypeSize(ishtar_services[id].type) * ((unsigned long)(ishtar_services[id].length)));// values
ssozonoff 0:086ea145b6d7 1024 }
ssozonoff 0:086ea145b6d7 1025 else
ssozonoff 0:086ea145b6d7 1026 {
ssozonoff 0:086ea145b6d7 1027 // skip
ssozonoff 0:086ea145b6d7 1028 ishtar_IncAddr(&addr, numberOfIndices * sizeof(ishtar_ValueVectorSize));// indices
ssozonoff 0:086ea145b6d7 1029 ishtar_IncAddr(&addr, ishtar_TypeSize(ishtar_services[id].type) * numberOfIndices);// values
ssozonoff 0:086ea145b6d7 1030 }
ssozonoff 0:086ea145b6d7 1031 }
ssozonoff 0:086ea145b6d7 1032 else
ssozonoff 0:086ea145b6d7 1033 {
ssozonoff 0:086ea145b6d7 1034 if (numberOfIndices == 0)
ssozonoff 0:086ea145b6d7 1035 {
ssozonoff 0:086ea145b6d7 1036 for (j = 0; j < ishtar_services[id].length; ++j)
ssozonoff 0:086ea145b6d7 1037 ishtar_SetValueInc((unsigned char*)ishtar_services[id].value,ishtar_services[id].type, j, &addr);
ssozonoff 0:086ea145b6d7 1038 }
ssozonoff 0:086ea145b6d7 1039 else
ssozonoff 0:086ea145b6d7 1040 {
ssozonoff 0:086ea145b6d7 1041 ishtar_IncAddr(&addr, numberOfIndices * sizeof(ishtar_ValueVectorSize));
ssozonoff 0:086ea145b6d7 1042
ssozonoff 0:086ea145b6d7 1043 // now addr points to the first value, indicesAddr to the first index
ssozonoff 0:086ea145b6d7 1044
ssozonoff 0:086ea145b6d7 1045 for (j = 0; j < numberOfIndices; ++j)
ssozonoff 0:086ea145b6d7 1046 {
ssozonoff 0:086ea145b6d7 1047 ishtar_AtInc(&indicesAddr, (unsigned char*)&indice, sizeof(ishtar_ValueVectorSize));
ssozonoff 0:086ea145b6d7 1048 // Problem, a corrupted message has been validated
ssozonoff 0:086ea145b6d7 1049 if (indice > ishtar_services[id].length)
ssozonoff 0:086ea145b6d7 1050 {
ssozonoff 0:086ea145b6d7 1051 ++ishtar_corruptedValidated;
ssozonoff 0:086ea145b6d7 1052 return;
ssozonoff 0:086ea145b6d7 1053 }
ssozonoff 0:086ea145b6d7 1054
ssozonoff 0:086ea145b6d7 1055 ishtar_SetValueInc((unsigned char*)ishtar_services[id].value, ishtar_services[id].type, (unsigned long)indice, &addr);
ssozonoff 0:086ea145b6d7 1056 }
ssozonoff 0:086ea145b6d7 1057 }
ssozonoff 0:086ea145b6d7 1058
ssozonoff 0:086ea145b6d7 1059 // call feedback function if existing
ssozonoff 0:086ea145b6d7 1060 if (ishtar_services[id].feedbackFunc)
ssozonoff 0:086ea145b6d7 1061 ishtar_services[id].feedbackFunc(&ishtar_services[id]);
ssozonoff 0:086ea145b6d7 1062 }
ssozonoff 0:086ea145b6d7 1063 }
ssozonoff 0:086ea145b6d7 1064 // SEND - the ack if feedback enabled
ssozonoff 0:086ea145b6d7 1065 if (feedback)
ssozonoff 0:086ea145b6d7 1066 {
ssozonoff 0:086ea145b6d7 1067 setAck = SET_ACK;
ssozonoff 0:086ea145b6d7 1068 answerSize = sizeof(ishtar_MessageId) + sizeof(ishtar_RequestId);
ssozonoff 0:086ea145b6d7 1069 sizeChecksum = ishtar_CalculateSizeChecksum(answerSize);
ssozonoff 0:086ea145b6d7 1070
ssozonoff 0:086ea145b6d7 1071 ishtar_SendHeader();
ssozonoff 0:086ea145b6d7 1072 // send size and size checksum
ssozonoff 0:086ea145b6d7 1073 ishtar_SendData((unsigned char*)(&answerSize), 4);
ssozonoff 0:086ea145b6d7 1074 ishtar_SendData((unsigned char*)(&sizeChecksum), 2);
ssozonoff 0:086ea145b6d7 1075
ssozonoff 0:086ea145b6d7 1076 // send content
ssozonoff 0:086ea145b6d7 1077 ishtar_InitCk();
ssozonoff 0:086ea145b6d7 1078 ishtar_SendData((unsigned char*)(&setAck), sizeof(ishtar_MessageId));
ssozonoff 0:086ea145b6d7 1079 ishtar_SendData((unsigned char*)(&requestID), sizeof(ishtar_RequestId));
ssozonoff 0:086ea145b6d7 1080 ishtar_SendCk();
ssozonoff 0:086ea145b6d7 1081
ssozonoff 0:086ea145b6d7 1082 ishtar_externalFlushFunc();
ssozonoff 0:086ea145b6d7 1083 }
ssozonoff 0:086ea145b6d7 1084 }
ssozonoff 0:086ea145b6d7 1085
ssozonoff 0:086ea145b6d7 1086 /*!
ssozonoff 0:086ea145b6d7 1087 * This function decodes the content of a disconnection packet and stops the snapshot.
ssozonoff 0:086ea145b6d7 1088 */
ssozonoff 0:086ea145b6d7 1089 void ishtar_HandleByeByeCall(unsigned char * addr, unsigned long len)
ssozonoff 0:086ea145b6d7 1090 {
ssozonoff 0:086ea145b6d7 1091 ishtar_snapshotActive = 0;
ssozonoff 0:086ea145b6d7 1092 ishtar_connected = 0;
ssozonoff 0:086ea145b6d7 1093 }
ssozonoff 0:086ea145b6d7 1094
ssozonoff 0:086ea145b6d7 1095 /*!
ssozonoff 0:086ea145b6d7 1096 * This function first checks if there is an active snapshot.
ssozonoff 0:086ea145b6d7 1097 * If yes, it sends the data for this snapshot.
ssozonoff 0:086ea145b6d7 1098 */
ssozonoff 0:086ea145b6d7 1099 void ishtar_Snapshot()
ssozonoff 0:086ea145b6d7 1100 {
ssozonoff 0:086ea145b6d7 1101 if (ishtar_snapshotActive && ishtar_connected)
ssozonoff 0:086ea145b6d7 1102 {
ssozonoff 0:086ea145b6d7 1103 ishtar_RequestId requestID;
ssozonoff 0:086ea145b6d7 1104
ssozonoff 0:086ea145b6d7 1105 unsigned long answerSize;// VALUES(4) + requestID(4) + size(4)
ssozonoff 0:086ea145b6d7 1106 unsigned short sizeChecksum;
ssozonoff 0:086ea145b6d7 1107 ishtar_ServiceId i;
ssozonoff 0:086ea145b6d7 1108 ishtar_ValueVectorSize j;
ssozonoff 0:086ea145b6d7 1109 ishtar_ValueVectorSize length;
ssozonoff 0:086ea145b6d7 1110
ssozonoff 0:086ea145b6d7 1111 ishtar_MessageId values;
ssozonoff 0:086ea145b6d7 1112
ssozonoff 0:086ea145b6d7 1113 answerSize = sizeof(ishtar_MessageId) + sizeof(ishtar_RequestId);
ssozonoff 0:086ea145b6d7 1114
ssozonoff 0:086ea145b6d7 1115 values = VALUES;
ssozonoff 0:086ea145b6d7 1116 requestID = ishtar_snapshotId;
ssozonoff 0:086ea145b6d7 1117
ssozonoff 0:086ea145b6d7 1118 // CALCULATE SIZE
ssozonoff 0:086ea145b6d7 1119 for (i = 0; i < ishtar_numberOfVariables; ++i)
ssozonoff 0:086ea145b6d7 1120 {
ssozonoff 0:086ea145b6d7 1121 // if the variable is in the snapshot
ssozonoff 0:086ea145b6d7 1122 if (ishtar_services[i].inSnapshot == 1)
ssozonoff 0:086ea145b6d7 1123 {
ssozonoff 0:086ea145b6d7 1124 // if the size is 0, it mean variable, so we must specify it.
ssozonoff 0:086ea145b6d7 1125 if (ishtar_services[i].length == 0)
ssozonoff 0:086ea145b6d7 1126 {
ssozonoff 0:086ea145b6d7 1127 answerSize += sizeof(ishtar_ValueVectorSize);
ssozonoff 0:086ea145b6d7 1128 answerSize += ishtar_Strlen((char*)(ishtar_services[i].value));
ssozonoff 0:086ea145b6d7 1129 }
ssozonoff 0:086ea145b6d7 1130 else
ssozonoff 0:086ea145b6d7 1131 {
ssozonoff 0:086ea145b6d7 1132 // in snapshots, the full variable is sent, cannot save indices in embedded version
ssozonoff 0:086ea145b6d7 1133 answerSize += ((unsigned long)(ishtar_services[i].length)) * ishtar_TypeSize(ishtar_services[i].type);
ssozonoff 0:086ea145b6d7 1134 }
ssozonoff 0:086ea145b6d7 1135 }
ssozonoff 0:086ea145b6d7 1136 }
ssozonoff 0:086ea145b6d7 1137
ssozonoff 0:086ea145b6d7 1138 ishtar_snapshotSize = answerSize;
ssozonoff 0:086ea145b6d7 1139 sizeChecksum = ishtar_CalculateSizeChecksum(answerSize);
ssozonoff 0:086ea145b6d7 1140
ssozonoff 0:086ea145b6d7 1141 // SEND
ssozonoff 0:086ea145b6d7 1142 ishtar_SendHeader();
ssozonoff 0:086ea145b6d7 1143 // send size and size checksum
ssozonoff 0:086ea145b6d7 1144 ishtar_SendData((unsigned char*)(&answerSize), 4);
ssozonoff 0:086ea145b6d7 1145 ishtar_SendData((unsigned char*)(&sizeChecksum), 2);
ssozonoff 0:086ea145b6d7 1146
ssozonoff 0:086ea145b6d7 1147 // send content
ssozonoff 0:086ea145b6d7 1148 ishtar_InitCk();
ssozonoff 0:086ea145b6d7 1149 ishtar_SendData((unsigned char*)(&values), sizeof(ishtar_MessageId));
ssozonoff 0:086ea145b6d7 1150 ishtar_SendData((unsigned char*)(&requestID), sizeof(ishtar_RequestId));
ssozonoff 0:086ea145b6d7 1151
ssozonoff 0:086ea145b6d7 1152 for (i = 0; i < ishtar_numberOfVariables; ++i)
ssozonoff 0:086ea145b6d7 1153 {
ssozonoff 0:086ea145b6d7 1154 if (ishtar_services[i].inSnapshot == 1)
ssozonoff 0:086ea145b6d7 1155 {
ssozonoff 0:086ea145b6d7 1156 // service id
ssozonoff 0:086ea145b6d7 1157 // length == 0 mean variable size, ONLY for char or UCHAR, with ended caracter equal to '\0'
ssozonoff 0:086ea145b6d7 1158 if (ishtar_services[i].length == 0 && ishtar_services[i].type == UCHAR)
ssozonoff 0:086ea145b6d7 1159 {
ssozonoff 0:086ea145b6d7 1160 length = ishtar_Strlen((char*)(ishtar_services[i].value));
ssozonoff 0:086ea145b6d7 1161 ishtar_SendData((unsigned char*)(&length), sizeof(ishtar_ValueVectorSize));
ssozonoff 0:086ea145b6d7 1162
ssozonoff 0:086ea145b6d7 1163 for (j = 0; j < length; ++j)
ssozonoff 0:086ea145b6d7 1164 {
ssozonoff 0:086ea145b6d7 1165 ishtar_SendValue((unsigned char*)ishtar_services[i].value, ishtar_services[i].type, j);
ssozonoff 0:086ea145b6d7 1166 }
ssozonoff 0:086ea145b6d7 1167
ssozonoff 0:086ea145b6d7 1168 }
ssozonoff 0:086ea145b6d7 1169 else
ssozonoff 0:086ea145b6d7 1170 {
ssozonoff 0:086ea145b6d7 1171 length = ishtar_services[i].length;
ssozonoff 0:086ea145b6d7 1172 for (j=0; j < length; ++j)
ssozonoff 0:086ea145b6d7 1173 {
ssozonoff 0:086ea145b6d7 1174 ishtar_SendValue((unsigned char*)ishtar_services[i].value, ishtar_services[i].type, j);
ssozonoff 0:086ea145b6d7 1175 }
ssozonoff 0:086ea145b6d7 1176 }
ssozonoff 0:086ea145b6d7 1177 }
ssozonoff 0:086ea145b6d7 1178 }
ssozonoff 0:086ea145b6d7 1179
ssozonoff 0:086ea145b6d7 1180 ishtar_SendCk();
ssozonoff 0:086ea145b6d7 1181
ssozonoff 0:086ea145b6d7 1182 ishtar_externalFlushFunc();
ssozonoff 0:086ea145b6d7 1183 }
ssozonoff 0:086ea145b6d7 1184 }
ssozonoff 0:086ea145b6d7 1185
ssozonoff 0:086ea145b6d7 1186
ssozonoff 0:086ea145b6d7 1187 /*!
ssozonoff 0:086ea145b6d7 1188 * This function reads the values from the memory and assign them to the Ishtar variables.
ssozonoff 0:086ea145b6d7 1189 *
ssozonoff 0:086ea145b6d7 1190 * It first read the checksum in the 2 first bytes and checks if it is correct, then it reads and assigns the value.
ssozonoff 0:086ea145b6d7 1191 * The checksum is used to invalidate memory data when the variable list is changed.
ssozonoff 0:086ea145b6d7 1192 */
ssozonoff 0:086ea145b6d7 1193 void ishtar_LoadFromMemory()
ssozonoff 0:086ea145b6d7 1194 {
ssozonoff 0:086ea145b6d7 1195 unsigned short i;
ssozonoff 0:086ea145b6d7 1196 unsigned short j;
ssozonoff 0:086ea145b6d7 1197 unsigned short size;
ssozonoff 0:086ea145b6d7 1198 unsigned short nameSize;
ssozonoff 0:086ea145b6d7 1199 unsigned short addr = ishtar_memoryMinAddress;
ssozonoff 0:086ea145b6d7 1200 unsigned char readChecksumA, readChecksumB;
ssozonoff 0:086ea145b6d7 1201
ssozonoff 0:086ea145b6d7 1202 if (!ishtar_memoryReadFunc)
ssozonoff 0:086ea145b6d7 1203 {
ssozonoff 0:086ea145b6d7 1204 ishtar_memoryError = READ_FUNC_NULL;
ssozonoff 0:086ea145b6d7 1205 return;
ssozonoff 0:086ea145b6d7 1206 }
ssozonoff 0:086ea145b6d7 1207
ssozonoff 0:086ea145b6d7 1208 // read checksum first
ssozonoff 0:086ea145b6d7 1209 if (ishtar_memoryReadFunc(addr++, &readChecksumA, 1) != 1)
ssozonoff 0:086ea145b6d7 1210 {
ssozonoff 0:086ea145b6d7 1211 ishtar_memoryError = READ_ERROR;
ssozonoff 0:086ea145b6d7 1212 return;
ssozonoff 0:086ea145b6d7 1213 }
ssozonoff 0:086ea145b6d7 1214 ishtar_numberOfBytesReadFromMemory += 1;
ssozonoff 0:086ea145b6d7 1215 if (ishtar_memoryReadFunc(addr++, &readChecksumB, 1) != 1)
ssozonoff 0:086ea145b6d7 1216 {
ssozonoff 0:086ea145b6d7 1217 ishtar_memoryError = READ_ERROR;
ssozonoff 0:086ea145b6d7 1218 return;
ssozonoff 0:086ea145b6d7 1219 }
ssozonoff 0:086ea145b6d7 1220 ishtar_numberOfBytesReadFromMemory += 1;
ssozonoff 0:086ea145b6d7 1221
ssozonoff 0:086ea145b6d7 1222 // verify checksums
ssozonoff 0:086ea145b6d7 1223 ishtar_memoryChecksumA = 0;
ssozonoff 0:086ea145b6d7 1224 ishtar_memoryChecksumB = 0;
ssozonoff 0:086ea145b6d7 1225
ssozonoff 0:086ea145b6d7 1226 for (i = 0; i < ishtar_numberOfVariables; ++i)
ssozonoff 0:086ea145b6d7 1227 {
ssozonoff 0:086ea145b6d7 1228 if (ishtar_services[i].flags & PERSISTENT)
ssozonoff 0:086ea145b6d7 1229 {
ssozonoff 0:086ea145b6d7 1230 // the id, type, length and name are used in the checksum
ssozonoff 0:086ea145b6d7 1231 ishtar_memoryChecksumA += (unsigned char)ishtar_services[i].type;
ssozonoff 0:086ea145b6d7 1232 ishtar_memoryChecksumB += ishtar_memoryChecksumA;
ssozonoff 0:086ea145b6d7 1233 ishtar_memoryChecksumA += (unsigned char)ishtar_services[i].length;
ssozonoff 0:086ea145b6d7 1234 ishtar_memoryChecksumB += ishtar_memoryChecksumA;
ssozonoff 0:086ea145b6d7 1235 ishtar_memoryChecksumA += (unsigned char)i;
ssozonoff 0:086ea145b6d7 1236 ishtar_memoryChecksumB += ishtar_memoryChecksumA;
ssozonoff 0:086ea145b6d7 1237
ssozonoff 0:086ea145b6d7 1238 nameSize = ishtar_Strlen(ishtar_services[i].name);
ssozonoff 0:086ea145b6d7 1239 for (j = 0; j < nameSize; ++j)
ssozonoff 0:086ea145b6d7 1240 {
ssozonoff 0:086ea145b6d7 1241 // checksum the name
ssozonoff 0:086ea145b6d7 1242 ishtar_memoryChecksumA += (unsigned char)ishtar_services[i].name[j];
ssozonoff 0:086ea145b6d7 1243 ishtar_memoryChecksumB += ishtar_memoryChecksumA;
ssozonoff 0:086ea145b6d7 1244 }
ssozonoff 0:086ea145b6d7 1245 }
ssozonoff 0:086ea145b6d7 1246 }
ssozonoff 0:086ea145b6d7 1247
ssozonoff 0:086ea145b6d7 1248 // checksum is wrong
ssozonoff 0:086ea145b6d7 1249 if (!(readChecksumA == ishtar_memoryChecksumA && readChecksumB == ishtar_memoryChecksumB))
ssozonoff 0:086ea145b6d7 1250 {
ssozonoff 0:086ea145b6d7 1251 ishtar_memoryError = CHECKSUM_WRONG;
ssozonoff 0:086ea145b6d7 1252 return;
ssozonoff 0:086ea145b6d7 1253 }
ssozonoff 0:086ea145b6d7 1254
ssozonoff 0:086ea145b6d7 1255 // assign the values
ssozonoff 0:086ea145b6d7 1256 for (i = 0; i < ishtar_numberOfVariables; ++i)
ssozonoff 0:086ea145b6d7 1257 {
ssozonoff 0:086ea145b6d7 1258 if (ishtar_services[i].flags & PERSISTENT)
ssozonoff 0:086ea145b6d7 1259 {
ssozonoff 0:086ea145b6d7 1260 // size of this variable in the memory
ssozonoff 0:086ea145b6d7 1261 size = (unsigned short)(ishtar_TypeSize(ishtar_services[i].type) * ishtar_services[i].length);
ssozonoff 0:086ea145b6d7 1262 // write value to memory
ssozonoff 0:086ea145b6d7 1263 if (size != ishtar_memoryReadFunc(addr, ishtar_services[i].value, size))
ssozonoff 0:086ea145b6d7 1264 {
ssozonoff 0:086ea145b6d7 1265 ishtar_memoryError = READ_ERROR;
ssozonoff 0:086ea145b6d7 1266 return;
ssozonoff 0:086ea145b6d7 1267 }
ssozonoff 0:086ea145b6d7 1268 addr += size;
ssozonoff 0:086ea145b6d7 1269 ishtar_numberOfBytesReadFromMemory += size;
ssozonoff 0:086ea145b6d7 1270
ssozonoff 0:086ea145b6d7 1271 // call feedback function if existing
ssozonoff 0:086ea145b6d7 1272 if (ishtar_services[i].feedbackFunc)
ssozonoff 0:086ea145b6d7 1273 ishtar_services[i].feedbackFunc(&ishtar_services[i]);
ssozonoff 0:086ea145b6d7 1274 }
ssozonoff 0:086ea145b6d7 1275 }
ssozonoff 0:086ea145b6d7 1276
ssozonoff 0:086ea145b6d7 1277 ishtar_memoryError = 0;
ssozonoff 0:086ea145b6d7 1278 }
ssozonoff 0:086ea145b6d7 1279
ssozonoff 0:086ea145b6d7 1280 /*!
ssozonoff 0:086ea145b6d7 1281 * This function writes the values of the Ishtar variables to the memory.
ssozonoff 0:086ea145b6d7 1282 *
ssozonoff 0:086ea145b6d7 1283 * It first checks that the is enough space in the memory, then it writes the checksum in the first 2 bytes, and then the values.
ssozonoff 0:086ea145b6d7 1284 */
ssozonoff 0:086ea145b6d7 1285 void ishtar_SaveToMemory()
ssozonoff 0:086ea145b6d7 1286 {
ssozonoff 0:086ea145b6d7 1287 unsigned short i;
ssozonoff 0:086ea145b6d7 1288 unsigned short j;
ssozonoff 0:086ea145b6d7 1289 unsigned short size = 2;
ssozonoff 0:086ea145b6d7 1290 unsigned short nameSize;
ssozonoff 0:086ea145b6d7 1291 unsigned short addr = ishtar_memoryMinAddress + 2;
ssozonoff 0:086ea145b6d7 1292
ssozonoff 0:086ea145b6d7 1293 if (!ishtar_memoryWriteFunc)
ssozonoff 0:086ea145b6d7 1294 {
ssozonoff 0:086ea145b6d7 1295 ishtar_memoryError = WRITE_FUNC_NULL;
ssozonoff 0:086ea145b6d7 1296 return;
ssozonoff 0:086ea145b6d7 1297 }
ssozonoff 0:086ea145b6d7 1298
ssozonoff 0:086ea145b6d7 1299 // check size
ssozonoff 0:086ea145b6d7 1300 for (i = 0; i < ishtar_numberOfVariables; ++i)
ssozonoff 0:086ea145b6d7 1301 {
ssozonoff 0:086ea145b6d7 1302 if (ishtar_services[i].flags & PERSISTENT)
ssozonoff 0:086ea145b6d7 1303 {
ssozonoff 0:086ea145b6d7 1304 size += ishtar_TypeSize(ishtar_services[i].type) * ishtar_services[i].length;
ssozonoff 0:086ea145b6d7 1305 }
ssozonoff 0:086ea145b6d7 1306 }
ssozonoff 0:086ea145b6d7 1307
ssozonoff 0:086ea145b6d7 1308 // checks if there is enough memory available
ssozonoff 0:086ea145b6d7 1309 if (ishtar_memoryMaxAddress - ishtar_memoryMinAddress < size)
ssozonoff 0:086ea145b6d7 1310 {
ssozonoff 0:086ea145b6d7 1311 ishtar_memoryError = NOT_ENOUGH_SPACE;
ssozonoff 0:086ea145b6d7 1312 return;
ssozonoff 0:086ea145b6d7 1313 }
ssozonoff 0:086ea145b6d7 1314
ssozonoff 0:086ea145b6d7 1315
ssozonoff 0:086ea145b6d7 1316 // write and calculate checksum
ssozonoff 0:086ea145b6d7 1317 ishtar_memoryChecksumA = 0;
ssozonoff 0:086ea145b6d7 1318 ishtar_memoryChecksumB = 0;
ssozonoff 0:086ea145b6d7 1319
ssozonoff 0:086ea145b6d7 1320 for (i = 0; i < ishtar_numberOfVariables; ++i)
ssozonoff 0:086ea145b6d7 1321 {
ssozonoff 0:086ea145b6d7 1322 if (ishtar_services[i].flags & PERSISTENT)
ssozonoff 0:086ea145b6d7 1323 {
ssozonoff 0:086ea145b6d7 1324 // the id, type, length and name are used in the checksum
ssozonoff 0:086ea145b6d7 1325 ishtar_memoryChecksumA += (unsigned char)ishtar_services[i].type;
ssozonoff 0:086ea145b6d7 1326 ishtar_memoryChecksumB += ishtar_memoryChecksumA;
ssozonoff 0:086ea145b6d7 1327 ishtar_memoryChecksumA += (unsigned char)ishtar_services[i].length;
ssozonoff 0:086ea145b6d7 1328 ishtar_memoryChecksumB += ishtar_memoryChecksumA;
ssozonoff 0:086ea145b6d7 1329 ishtar_memoryChecksumA += (unsigned char)i;
ssozonoff 0:086ea145b6d7 1330 ishtar_memoryChecksumB += ishtar_memoryChecksumA;
ssozonoff 0:086ea145b6d7 1331
ssozonoff 0:086ea145b6d7 1332 nameSize = ishtar_Strlen(ishtar_services[i].name);
ssozonoff 0:086ea145b6d7 1333 for (j = 0; j < nameSize; ++j)
ssozonoff 0:086ea145b6d7 1334 {
ssozonoff 0:086ea145b6d7 1335 // checksum the name
ssozonoff 0:086ea145b6d7 1336 ishtar_memoryChecksumA += (unsigned char)ishtar_services[i].name[j];
ssozonoff 0:086ea145b6d7 1337 ishtar_memoryChecksumB += ishtar_memoryChecksumA;
ssozonoff 0:086ea145b6d7 1338 }
ssozonoff 0:086ea145b6d7 1339
ssozonoff 0:086ea145b6d7 1340 // size of this variable in the memory
ssozonoff 0:086ea145b6d7 1341 size = (unsigned short)(ishtar_TypeSize(ishtar_services[i].type) * ishtar_services[i].length);
ssozonoff 0:086ea145b6d7 1342 // write value to memory
ssozonoff 0:086ea145b6d7 1343 if (size != ishtar_memoryWriteFunc(addr, ishtar_services[i].value, size))
ssozonoff 0:086ea145b6d7 1344 {
ssozonoff 0:086ea145b6d7 1345 ishtar_memoryError = WRITE_ERROR;
ssozonoff 0:086ea145b6d7 1346 return;
ssozonoff 0:086ea145b6d7 1347 }
ssozonoff 0:086ea145b6d7 1348 addr += size;
ssozonoff 0:086ea145b6d7 1349 ishtar_numberOfBytesWrittenToMemory += size;
ssozonoff 0:086ea145b6d7 1350 }
ssozonoff 0:086ea145b6d7 1351 }
ssozonoff 0:086ea145b6d7 1352
ssozonoff 0:086ea145b6d7 1353 // end writing checksum
ssozonoff 0:086ea145b6d7 1354 if (ishtar_memoryWriteFunc(ishtar_memoryMinAddress, &ishtar_memoryChecksumA, 1) != 1)
ssozonoff 0:086ea145b6d7 1355 {
ssozonoff 0:086ea145b6d7 1356 ishtar_memoryError = WRITE_ERROR;
ssozonoff 0:086ea145b6d7 1357 return;
ssozonoff 0:086ea145b6d7 1358 }
ssozonoff 0:086ea145b6d7 1359 ishtar_numberOfBytesWrittenToMemory += 1;
ssozonoff 0:086ea145b6d7 1360 if (ishtar_memoryWriteFunc(ishtar_memoryMinAddress + 1, &ishtar_memoryChecksumB, 1) != 1)
ssozonoff 0:086ea145b6d7 1361 {
ssozonoff 0:086ea145b6d7 1362 ishtar_memoryError = WRITE_ERROR;
ssozonoff 0:086ea145b6d7 1363 return;
ssozonoff 0:086ea145b6d7 1364 }
ssozonoff 0:086ea145b6d7 1365 ishtar_numberOfBytesWrittenToMemory += 1;
ssozonoff 0:086ea145b6d7 1366
ssozonoff 0:086ea145b6d7 1367 ishtar_memoryError = NO_ERROR;
ssozonoff 0:086ea145b6d7 1368 }
ssozonoff 0:086ea145b6d7 1369
ssozonoff 0:086ea145b6d7 1370 // init
ssozonoff 0:086ea145b6d7 1371
ssozonoff 0:086ea145b6d7 1372
ssozonoff 0:086ea145b6d7 1373 /*!
ssozonoff 0:086ea145b6d7 1374 * This function inits Ishtar Embedded server
ssozonoff 0:086ea145b6d7 1375 *
ssozonoff 0:086ea145b6d7 1376 * @param externalSendFunc The external function to send data
ssozonoff 0:086ea145b6d7 1377 * @param externalFlushFunc The external function to flush data output buffer
ssozonoff 0:086ea145b6d7 1378 *
ssozonoff 0:086ea145b6d7 1379 **/
ssozonoff 0:086ea145b6d7 1380 void ishtar_Init(ishtar_ExternalSendFunc externalSendFunc, ishtar_ExternalFlushFunc externalFlushFunc)
ssozonoff 0:086ea145b6d7 1381 {
ssozonoff 0:086ea145b6d7 1382 ishtar_externalSendFunc = externalSendFunc;
ssozonoff 0:086ea145b6d7 1383 ishtar_externalSendBlockingFunc = externalSendFunc;
ssozonoff 0:086ea145b6d7 1384 ishtar_currentSendFunc = externalSendFunc;
ssozonoff 0:086ea145b6d7 1385
ssozonoff 0:086ea145b6d7 1386 if (externalFlushFunc)
ssozonoff 0:086ea145b6d7 1387 {
ssozonoff 0:086ea145b6d7 1388 ishtar_externalFlushFunc = externalFlushFunc;
ssozonoff 0:086ea145b6d7 1389 }
ssozonoff 0:086ea145b6d7 1390 else
ssozonoff 0:086ea145b6d7 1391 {
ssozonoff 0:086ea145b6d7 1392 ishtar_externalFlushFunc = &ishtar_DoNothing;
ssozonoff 0:086ea145b6d7 1393 }
ssozonoff 0:086ea145b6d7 1394
ssozonoff 0:086ea145b6d7 1395 ishtar_InitBuffer();
ssozonoff 0:086ea145b6d7 1396
ssozonoff 0:086ea145b6d7 1397 // DEBUG
ssozonoff 0:086ea145b6d7 1398 #if ISHTAR_DEBUG
ssozonoff 0:086ea145b6d7 1399 ishtar_RegisterDebugVars();
ssozonoff 0:086ea145b6d7 1400 #endif
ssozonoff 0:086ea145b6d7 1401
ssozonoff 0:086ea145b6d7 1402 }
ssozonoff 0:086ea145b6d7 1403
ssozonoff 0:086ea145b6d7 1404 /*!
ssozonoff 0:086ea145b6d7 1405 * This function inits Ishtar Embedded server with the use of
ssozonoff 0:086ea145b6d7 1406 * a different sending function for big messages.
ssozonoff 0:086ea145b6d7 1407 * The HELLO and SERVICE_LIST packets use the blocking function, other packets the non-blocking
ssozonoff 0:086ea145b6d7 1408 *
ssozonoff 0:086ea145b6d7 1409 * WARNING: Using this function may cause the host to stuck for a while when the client asks for
ssozonoff 0:086ea145b6d7 1410 * the list of all services, as the blocking function could take *several seconds* to send the data
ssozonoff 0:086ea145b6d7 1411 *
ssozonoff 0:086ea145b6d7 1412 * @param externalSendFunc The external function to send data
ssozonoff 0:086ea145b6d7 1413 * @param externalSendBlockFunc The external blocking function to send data (big packets)
ssozonoff 0:086ea145b6d7 1414 * @param externalFlushFunc The external function to flush data output buffer
ssozonoff 0:086ea145b6d7 1415 *
ssozonoff 0:086ea145b6d7 1416 **/
ssozonoff 0:086ea145b6d7 1417 void ishtar_InitWithBlock(ishtar_ExternalSendFunc externalSendFunc, ishtar_ExternalSendFunc externalSendBlockFunc, ishtar_ExternalFlushFunc externalFlushFunc)
ssozonoff 0:086ea145b6d7 1418 {
ssozonoff 0:086ea145b6d7 1419 ishtar_externalSendFunc = externalSendFunc;
ssozonoff 0:086ea145b6d7 1420 ishtar_externalSendBlockingFunc = externalSendBlockFunc;
ssozonoff 0:086ea145b6d7 1421 ishtar_currentSendFunc = externalSendFunc;
ssozonoff 0:086ea145b6d7 1422
ssozonoff 0:086ea145b6d7 1423 if (externalFlushFunc)
ssozonoff 0:086ea145b6d7 1424 {
ssozonoff 0:086ea145b6d7 1425 ishtar_externalFlushFunc = externalFlushFunc;
ssozonoff 0:086ea145b6d7 1426 }
ssozonoff 0:086ea145b6d7 1427 else
ssozonoff 0:086ea145b6d7 1428 {
ssozonoff 0:086ea145b6d7 1429 ishtar_externalFlushFunc = &ishtar_DoNothing;
ssozonoff 0:086ea145b6d7 1430 }
ssozonoff 0:086ea145b6d7 1431
ssozonoff 0:086ea145b6d7 1432 ishtar_InitBuffer();
ssozonoff 0:086ea145b6d7 1433
ssozonoff 0:086ea145b6d7 1434 // DEBUG
ssozonoff 0:086ea145b6d7 1435 #if ISHTAR_DEBUG
ssozonoff 0:086ea145b6d7 1436 ishtar_RegisterDebugVars();
ssozonoff 0:086ea145b6d7 1437 #endif
ssozonoff 0:086ea145b6d7 1438 }
ssozonoff 0:086ea145b6d7 1439
ssozonoff 0:086ea145b6d7 1440 /*!
ssozonoff 0:086ea145b6d7 1441 * This function inits the receive buffers and pointers.
ssozonoff 0:086ea145b6d7 1442 */
ssozonoff 0:086ea145b6d7 1443 void ishtar_InitBuffer()
ssozonoff 0:086ea145b6d7 1444 {
ssozonoff 0:086ea145b6d7 1445 ishtar_bufBegin = ishtar_buffer;
ssozonoff 0:086ea145b6d7 1446 ishtar_bufEnd = ishtar_buffer + ISHTAR_BUFFER_SIZE;
ssozonoff 0:086ea145b6d7 1447 ishtar_bufPos = ishtar_buffer;
ssozonoff 0:086ea145b6d7 1448
ssozonoff 0:086ea145b6d7 1449 ishtar_consumePos = ishtar_buffer;
ssozonoff 0:086ea145b6d7 1450
ssozonoff 0:086ea145b6d7 1451 ishtar_packetBegin = ishtar_buffer;
ssozonoff 0:086ea145b6d7 1452 }
ssozonoff 0:086ea145b6d7 1453
ssozonoff 0:086ea145b6d7 1454 /*!
ssozonoff 0:086ea145b6d7 1455 * This function directly registers several variables to monitor Ishtar itself
ssozonoff 0:086ea145b6d7 1456 */
ssozonoff 0:086ea145b6d7 1457 void ishtar_RegisterDebugVars()
ssozonoff 0:086ea145b6d7 1458 {
ssozonoff 0:086ea145b6d7 1459 ishtar_Variable("ishtar.overflows", (unsigned char*)(&ishtar_numberOfOverflows), UINT, 1, 0);
ssozonoff 0:086ea145b6d7 1460 ishtar_Variable("ishtar.variables", (unsigned char*)(&ishtar_numberOfVariables), USHORT, 1, 0);
ssozonoff 0:086ea145b6d7 1461 ishtar_Variable("ishtar.dropHeader1", (unsigned char*)(&ishtar_numberOfDropHeader1), UINT, 1, 0);
ssozonoff 0:086ea145b6d7 1462 ishtar_Variable("ishtar.dropHeader2", (unsigned char*)(&ishtar_numberOfDropHeader2), UINT, 1, 0);
ssozonoff 0:086ea145b6d7 1463 ishtar_Variable("ishtar.dropHeader3", (unsigned char*)(&ishtar_numberOfDropHeader3), UINT, 1, 0);
ssozonoff 0:086ea145b6d7 1464 ishtar_Variable("ishtar.dropHeader4", (unsigned char*)(&ishtar_numberOfDropHeader4), UINT, 1, 0);
ssozonoff 0:086ea145b6d7 1465 ishtar_Variable("ishtar.dropSize", (unsigned char*)(&ishtar_numberOfDropSize), UINT, 1, 0);
ssozonoff 0:086ea145b6d7 1466 ishtar_Variable("ishtar.dropContent", (unsigned char*)(&ishtar_numberOfDropContent), UINT, 1, 0);
ssozonoff 0:086ea145b6d7 1467 ishtar_Variable("ishtar.bytesSent", (unsigned char*)(&ishtar_numberOfBytesSent), UINT, 1, 0);
ssozonoff 0:086ea145b6d7 1468 ishtar_Variable("ishtar.bytesReceived", (unsigned char*)(&ishtar_numberOfBytesReceived), UINT, 1, 0);
ssozonoff 0:086ea145b6d7 1469 ishtar_Variable("ishtar.validMessages", (unsigned char*)(&ishtar_numberOfValidMessages), UINT, 1, 0);
ssozonoff 0:086ea145b6d7 1470 ishtar_Variable("ishtar.memoryBytesRead", (unsigned char*)(&ishtar_numberOfBytesReadFromMemory), UINT, 1, 0);
ssozonoff 0:086ea145b6d7 1471 ishtar_Variable("ishtar.memoryBytesWritten", (unsigned char*)(&ishtar_numberOfBytesWrittenToMemory), UINT, 1, 0);
ssozonoff 0:086ea145b6d7 1472 ishtar_Variable("ishtar.memoryError", (unsigned char*)(&ishtar_memoryError), UCHAR, 1, 0);
ssozonoff 0:086ea145b6d7 1473 ishtar_Variable("ishtar.snapshotSize", (unsigned char*)(&ishtar_snapshotSize), UINT, 1, 0);
ssozonoff 0:086ea145b6d7 1474 }
ssozonoff 0:086ea145b6d7 1475
ssozonoff 0:086ea145b6d7 1476 /*!
ssozonoff 0:086ea145b6d7 1477 * This function inits the non-volatile memory access functions
ssozonoff 0:086ea145b6d7 1478 *
ssozonoff 0:086ea145b6d7 1479 * @param memoryReadFunc A pointer to the external function that reads the non-volatile memory
ssozonoff 0:086ea145b6d7 1480 * @param memoryWriteFunc A pointer to the external function that writes the non-volatile memory
ssozonoff 0:086ea145b6d7 1481 * @param minAddress The lowest memory address that Ishtar is allowed to write
ssozonoff 0:086ea145b6d7 1482 * @param maxAddress The highest memory address that Ishtar is allowed to write
ssozonoff 0:086ea145b6d7 1483 */
ssozonoff 0:086ea145b6d7 1484 void ishtar_InitMemoryAccess(ishtar_MemoryReadFunc memoryReadFunc, ishtar_MemoryWriteFunc memoryWriteFunc, unsigned short minAddress, unsigned short maxAddress)
ssozonoff 0:086ea145b6d7 1485 {
ssozonoff 0:086ea145b6d7 1486 ishtar_memoryReadFunc = memoryReadFunc;
ssozonoff 0:086ea145b6d7 1487 ishtar_memoryWriteFunc = memoryWriteFunc;
ssozonoff 0:086ea145b6d7 1488
ssozonoff 0:086ea145b6d7 1489 ishtar_memoryMinAddress = minAddress;
ssozonoff 0:086ea145b6d7 1490 ishtar_memoryMaxAddress = maxAddress;
ssozonoff 0:086ea145b6d7 1491 }
ssozonoff 0:086ea145b6d7 1492
ssozonoff 0:086ea145b6d7 1493 /*!
ssozonoff 0:086ea145b6d7 1494 * This function registers a variable into Ishtar in order to make it accessible to external clients
ssozonoff 0:086ea145b6d7 1495 *
ssozonoff 0:086ea145b6d7 1496 * @param name The textual name of the variable. Use '.' character to create sub-groups, e.g. "gps.position.longitude"
ssozonoff 0:086ea145b6d7 1497 * @param var A pointer to the real variable or to the root of the array of variables
ssozonoff 0:086ea145b6d7 1498 * @param type The type of the variable : BOOL, CHAR, UCHAR, SHORT, USHORT, INT, UINT, FLOAT, DOUBLE
ssozonoff 0:086ea145b6d7 1499 * @param length The number of elements in the array, or 1 for a normal variable
ssozonoff 0:086ea145b6d7 1500 * @param flags The flags for this variable : 0 or READ_ONLY
ssozonoff 0:086ea145b6d7 1501 */
ssozonoff 0:086ea145b6d7 1502 ishtar_ServiceId ishtar_Variable(const char* name, void* var, ishtar_ValueVectorType type, ishtar_ValueVectorSize length, ishtar_ServiceFlags flags)
ssozonoff 0:086ea145b6d7 1503 {
ssozonoff 0:086ea145b6d7 1504 return ishtar_VariableFeedback(name, var, type, length, flags, 0);
ssozonoff 0:086ea145b6d7 1505 }
ssozonoff 0:086ea145b6d7 1506
ssozonoff 0:086ea145b6d7 1507 /*!
ssozonoff 0:086ea145b6d7 1508 * This function registers a variable into Ishtar in order to make it accessible to external clients
ssozonoff 0:086ea145b6d7 1509 *
ssozonoff 0:086ea145b6d7 1510 * @param name The textual name of the variable. Use '.' character to create sub-groups, e.g. "gps.position.longitude"
ssozonoff 0:086ea145b6d7 1511 * @param var A pointer to the real variable or to the root of the array of variables
ssozonoff 0:086ea145b6d7 1512 * @param type The type of the variable : BOOL, CHAR, UCHAR, SHORT, USHORT, INT, UINT, FLOAT, DOUBLE
ssozonoff 0:086ea145b6d7 1513 * @param length The number of elements in the array, or 1 for a normal variable
ssozonoff 0:086ea145b6d7 1514 * @param flags The flags for this variable : 0 or READ_ONLY
ssozonoff 0:086ea145b6d7 1515 * @param feedbackFunc Pointer to a function called whenever the corresponding variable is modified.
ssozonoff 0:086ea145b6d7 1516 */
ssozonoff 0:086ea145b6d7 1517 ishtar_ServiceId ishtar_VariableFeedback(const char* name, void* var, ishtar_ValueVectorType type, ishtar_ValueVectorSize length, ishtar_ServiceFlags flags, ishtar_VariableModifiedFunc feedbackFunc)
ssozonoff 0:086ea145b6d7 1518 {
ssozonoff 0:086ea145b6d7 1519 if (ishtar_numberOfVariables < ISHTAR_MAX_NUMBER_OF_SERVICES)
ssozonoff 0:086ea145b6d7 1520 {
ssozonoff 0:086ea145b6d7 1521 // If the length == 0, then the variable must be read-only because there is no dynamic allocation
ssozonoff 0:086ea145b6d7 1522 if (length == 0)
ssozonoff 0:086ea145b6d7 1523 {
ssozonoff 0:086ea145b6d7 1524 flags |= READ_ONLY;
ssozonoff 0:086ea145b6d7 1525 }
ssozonoff 0:086ea145b6d7 1526 ishtar_services[ishtar_numberOfVariables].name = name;
ssozonoff 0:086ea145b6d7 1527 ishtar_services[ishtar_numberOfVariables].type = type;
ssozonoff 0:086ea145b6d7 1528 ishtar_services[ishtar_numberOfVariables].length = length;
ssozonoff 0:086ea145b6d7 1529 ishtar_services[ishtar_numberOfVariables].flags = flags;
ssozonoff 0:086ea145b6d7 1530 ishtar_services[ishtar_numberOfVariables].value = var;
ssozonoff 0:086ea145b6d7 1531 ishtar_services[ishtar_numberOfVariables].inSnapshot = 0;
ssozonoff 0:086ea145b6d7 1532 ishtar_services[ishtar_numberOfVariables].feedbackFunc = feedbackFunc;
ssozonoff 0:086ea145b6d7 1533
ssozonoff 0:086ea145b6d7 1534
ssozonoff 0:086ea145b6d7 1535 return ishtar_numberOfVariables++;
ssozonoff 0:086ea145b6d7 1536 }
ssozonoff 0:086ea145b6d7 1537 return 0;
ssozonoff 0:086ea145b6d7 1538 }
ssozonoff 0:086ea145b6d7 1539
ssozonoff 0:086ea145b6d7 1540
ssozonoff 0:086ea145b6d7 1541 /*!
ssozonoff 0:086ea145b6d7 1542 * This function calculates the length of a zero-terminated string
ssozonoff 0:086ea145b6d7 1543 *
ssozonoff 0:086ea145b6d7 1544 * @param The zero-terminated string for which the length will be calculated
ssozonoff 0:086ea145b6d7 1545 * @return The length of the string or ISHTAR_STRING_MAX_SIZE if the string is too long (to prevent from getting stuck)
ssozonoff 0:086ea145b6d7 1546 */
ssozonoff 0:086ea145b6d7 1547 unsigned long ishtar_Strlen(const char * addr)
ssozonoff 0:086ea145b6d7 1548 {
ssozonoff 0:086ea145b6d7 1549 unsigned long l = 0;
ssozonoff 0:086ea145b6d7 1550 while (*addr != '\0' && l < ISHTAR_STRING_MAX_SIZE)
ssozonoff 0:086ea145b6d7 1551 {
ssozonoff 0:086ea145b6d7 1552 ++l;
ssozonoff 0:086ea145b6d7 1553 ++addr;
ssozonoff 0:086ea145b6d7 1554 }
ssozonoff 0:086ea145b6d7 1555 return l;
ssozonoff 0:086ea145b6d7 1556 }
ssozonoff 0:086ea145b6d7 1557
ssozonoff 0:086ea145b6d7 1558 /*!
ssozonoff 0:086ea145b6d7 1559 * This function returns the number of bytes taken by a variable of a certain type
ssozonoff 0:086ea145b6d7 1560 *
ssozonoff 0:086ea145b6d7 1561 * @param type The IShtar-defined type of the variable : BOOL, CHAR, UCHAR, SHORT, USHORT, INT, UINT, FLOAT, DOUBLE
ssozonoff 0:086ea145b6d7 1562 */
ssozonoff 0:086ea145b6d7 1563 unsigned long ishtar_TypeSize(ishtar_ValueVectorType type)
ssozonoff 0:086ea145b6d7 1564 {
ssozonoff 0:086ea145b6d7 1565 unsigned long size = 0;
ssozonoff 0:086ea145b6d7 1566 if (type == CHAR || type == UCHAR || type == BOOL)
ssozonoff 0:086ea145b6d7 1567 {
ssozonoff 0:086ea145b6d7 1568 size = sizeof(char);
ssozonoff 0:086ea145b6d7 1569 }
ssozonoff 0:086ea145b6d7 1570 else if (type == SHORT || type == USHORT)
ssozonoff 0:086ea145b6d7 1571 {
ssozonoff 0:086ea145b6d7 1572 size = sizeof(short);
ssozonoff 0:086ea145b6d7 1573 }
ssozonoff 0:086ea145b6d7 1574 else if (type == FLOAT || type == INT || type == UINT)
ssozonoff 0:086ea145b6d7 1575 {
ssozonoff 0:086ea145b6d7 1576 size = sizeof(long);
ssozonoff 0:086ea145b6d7 1577 }
ssozonoff 0:086ea145b6d7 1578 else if (type == DOUBLE)
ssozonoff 0:086ea145b6d7 1579 {
ssozonoff 0:086ea145b6d7 1580 size = sizeof(double);
ssozonoff 0:086ea145b6d7 1581 }
ssozonoff 0:086ea145b6d7 1582 return size;
ssozonoff 0:086ea145b6d7 1583 }
ssozonoff 0:086ea145b6d7 1584
ssozonoff 0:086ea145b6d7 1585 /*!
ssozonoff 0:086ea145b6d7 1586 * This function returns true if the server already received a HELLO message since it started, false otherwise
ssozonoff 0:086ea145b6d7 1587 */
ssozonoff 0:086ea145b6d7 1588 unsigned char ishtar_IsConnected()
ssozonoff 0:086ea145b6d7 1589 {
ssozonoff 0:086ea145b6d7 1590 return ishtar_connected;
ssozonoff 0:086ea145b6d7 1591 }
ssozonoff 0:086ea145b6d7 1592
ssozonoff 0:086ea145b6d7 1593 unsigned short ishtar_ServiceCount()
ssozonoff 0:086ea145b6d7 1594 {
ssozonoff 0:086ea145b6d7 1595 return ishtar_numberOfVariables;
ssozonoff 0:086ea145b6d7 1596 }
ssozonoff 0:086ea145b6d7 1597
ssozonoff 0:086ea145b6d7 1598
ssozonoff 0:086ea145b6d7 1599 #ifdef __cplusplus
ssozonoff 0:086ea145b6d7 1600 }
ssozonoff 0:086ea145b6d7 1601 #endif