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
ishtar.cpp@0:086ea145b6d7, 2011-05-12 (annotated)
- Committer:
- ssozonoff
- Date:
- Thu May 12 08:30:17 2011 +0000
- Revision:
- 0:086ea145b6d7
Who changed what in which revision?
User | Revision | Line number | New 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 |