Committer:
sblair
Date:
Fri Oct 07 13:41:08 2011 +0000
Revision:
0:230c10b228ea
Child:
1:9399d44c2b1a

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sblair 0:230c10b228ea 1 #include "svPacketData.h"
sblair 0:230c10b228ea 2 #include "svEncode.h"
sblair 0:230c10b228ea 3 #include "gseEncode.h"
sblair 0:230c10b228ea 4 #include "encodePacket.h"
sblair 0:230c10b228ea 5
sblair 0:230c10b228ea 6
sblair 0:230c10b228ea 7 int svASDULength(struct svData *svData) {
sblair 0:230c10b228ea 8 int len = 0;
sblair 0:230c10b228ea 9
sblair 0:230c10b228ea 10 len += strlen((const char *) svData->ASDU[0].svID) + 2;
sblair 0:230c10b228ea 11 //printf("%i, %s\n", strlen(svData->ASDU[0].svID), svData->ASDU[0].svID);
sblair 0:230c10b228ea 12 //len += strlen((const char *) svData->ASDU[0].datset) + 2;
sblair 0:230c10b228ea 13 len += BER_GET_LENGTH_CTYPE_INT16U(&svData->ASDU[0].smpCnt) + 2;
sblair 0:230c10b228ea 14 len += BER_GET_LENGTH_CTYPE_INT32U(&svData->ASDU[0].confRev) + 2;
sblair 0:230c10b228ea 15 len += SV_GET_LENGTH_BOOLEAN + 2;
sblair 0:230c10b228ea 16 //len += BER_GET_LENGTH_CTYPE_INT16U(&svData->ASDU[0].smpRate) + 2;
sblair 0:230c10b228ea 17 len += svData->ASDU[0].data.size + getLengthBytes(svData->ASDU[0].data.size);
sblair 0:230c10b228ea 18 len++;
sblair 0:230c10b228ea 19
sblair 0:230c10b228ea 20 return len;
sblair 0:230c10b228ea 21 }
sblair 0:230c10b228ea 22
sblair 0:230c10b228ea 23 int svSeqLength(struct svData *svData) {
sblair 0:230c10b228ea 24 int len = svASDULength(svData);
sblair 0:230c10b228ea 25 len += getLengthBytes(len);
sblair 0:230c10b228ea 26 len++;
sblair 0:230c10b228ea 27 len = len * svData->noASDU; // assume all ASDUs are the same size
sblair 0:230c10b228ea 28
sblair 0:230c10b228ea 29 return len;
sblair 0:230c10b228ea 30 }
sblair 0:230c10b228ea 31
sblair 0:230c10b228ea 32 int svAPDULength(struct svData *svData) {
sblair 0:230c10b228ea 33 int len = svSeqLength(svData);
sblair 0:230c10b228ea 34 len += getLengthBytes(len);
sblair 0:230c10b228ea 35 len++;
sblair 0:230c10b228ea 36
sblair 0:230c10b228ea 37 len += 3;
sblair 0:230c10b228ea 38
sblair 0:230c10b228ea 39 return len;
sblair 0:230c10b228ea 40 }
sblair 0:230c10b228ea 41
sblair 0:230c10b228ea 42
sblair 0:230c10b228ea 43 //TODO: convert to proper BER sizes
sblair 0:230c10b228ea 44 // creates an SV packet, including frame header. returns 0 on fail; number of bytes on success
sblair 0:230c10b228ea 45 int svEncodePacket(struct svData *svData, unsigned char *buf) {
sblair 0:230c10b228ea 46 int offset = 0;
sblair 0:230c10b228ea 47 int len = svAPDULength(svData);
sblair 0:230c10b228ea 48 len += getLengthBytes(len);
sblair 0:230c10b228ea 49 len += 9; // savPdu tag size (1 byte), plus 8 "header" bytes
sblair 0:230c10b228ea 50
sblair 0:230c10b228ea 51 // frame header
sblair 0:230c10b228ea 52 memcpy(&buf[offset], svData->ethHeaderData.destMACAddress, 6); // destination MAC addresses
sblair 0:230c10b228ea 53 offset += 6;
sblair 0:230c10b228ea 54 memcpy(&buf[offset], LOCAL_MAC_ADDRESS, 6); // source MAC addresses
sblair 0:230c10b228ea 55 offset += 6;
sblair 0:230c10b228ea 56
sblair 0:230c10b228ea 57 buf[offset++] = 0x81; // TPID
sblair 0:230c10b228ea 58 buf[offset++] = 0x00;
sblair 0:230c10b228ea 59
sblair 0:230c10b228ea 60 netmemcpy(&buf[offset], &svData->ethHeaderData.VLAN_ID, 2); // TCI
sblair 0:230c10b228ea 61 buf[offset] |= (svData->ethHeaderData.VLAN_PRIORITY << 5);
sblair 0:230c10b228ea 62 offset += 2;
sblair 0:230c10b228ea 63
sblair 0:230c10b228ea 64 buf[offset++] = 0x88; // EtherType
sblair 0:230c10b228ea 65 buf[offset++] = 0xBA;
sblair 0:230c10b228ea 66
sblair 0:230c10b228ea 67 netmemcpy(&buf[offset], &svData->ethHeaderData.APPID, 2); // APPID
sblair 0:230c10b228ea 68 offset += 2;
sblair 0:230c10b228ea 69
sblair 0:230c10b228ea 70 netmemcpy(&buf[offset], &len, 2); // length
sblair 0:230c10b228ea 71 offset += 2;
sblair 0:230c10b228ea 72
sblair 0:230c10b228ea 73 buf[offset++] = 0x00; // reserved 1
sblair 0:230c10b228ea 74 buf[offset++] = 0x00;
sblair 0:230c10b228ea 75 buf[offset++] = 0x00; // reserved 2
sblair 0:230c10b228ea 76 buf[offset++] = 0x00;
sblair 0:230c10b228ea 77
sblair 0:230c10b228ea 78 buf[offset++] = 0x60;
sblair 0:230c10b228ea 79 offset += encodeLength(&buf[offset], svAPDULength(svData));
sblair 0:230c10b228ea 80
sblair 0:230c10b228ea 81 //TODO noASDU may be > 126?
sblair 0:230c10b228ea 82 buf[offset++] = 0x80;
sblair 0:230c10b228ea 83 buf[offset++] = 1;
sblair 0:230c10b228ea 84 buf[offset++] = (unsigned char) svData->noASDU;
sblair 0:230c10b228ea 85
sblair 0:230c10b228ea 86 buf[offset++] = 0xA2;
sblair 0:230c10b228ea 87 offset += encodeLength(&buf[offset], svSeqLength(svData));
sblair 0:230c10b228ea 88
sblair 0:230c10b228ea 89 int i = 0;
sblair 0:230c10b228ea 90 int size = 0;
sblair 0:230c10b228ea 91 for (i = 0; i < svData->noASDU; i++) {
sblair 0:230c10b228ea 92 buf[offset++] = 0x30;
sblair 0:230c10b228ea 93 offset += encodeLength(&buf[offset], svASDULength(svData));
sblair 0:230c10b228ea 94
sblair 0:230c10b228ea 95 size = strlen((const char *) svData->ASDU[i].svID);
sblair 0:230c10b228ea 96 buf[offset++] = 0x80;
sblair 0:230c10b228ea 97 buf[offset++] = size;
sblair 0:230c10b228ea 98 memcpy(&buf[offset], svData->ASDU[i].svID, size);
sblair 0:230c10b228ea 99 offset += size;
sblair 0:230c10b228ea 100
sblair 0:230c10b228ea 101 /*size = strlen(svData->ASDU[i].datset);
sblair 0:230c10b228ea 102 buf[offset++] = 0x81;
sblair 0:230c10b228ea 103 buf[offset++] = size;
sblair 0:230c10b228ea 104 memcpy(&buf[offset], svData->ASDU[i].datset, size);
sblair 0:230c10b228ea 105 offset += size;*/
sblair 0:230c10b228ea 106
sblair 0:230c10b228ea 107 buf[offset++] = 0x82;
sblair 0:230c10b228ea 108 offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_INT16U(&svData->ASDU[i].smpCnt));
sblair 0:230c10b228ea 109 offset += ber_encode_integer(&buf[offset], &svData->ASDU[i].smpCnt, SV_GET_LENGTH_INT16U);
sblair 0:230c10b228ea 110 //buf[offset++] = BER_GET_LENGTH_CTYPE_INT16U(&svData->ASDU[i].smpCnt);
sblair 0:230c10b228ea 111 //offset += BER_ENCODE_CTYPE_INT16U(&buf[offset], &svData->ASDU[i].smpCnt);
sblair 0:230c10b228ea 112
sblair 0:230c10b228ea 113 buf[offset++] = 0x83;
sblair 0:230c10b228ea 114 offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_INT32U(&svData->ASDU[i].confRev));
sblair 0:230c10b228ea 115 offset += ber_encode_integer(&buf[offset], &svData->ASDU[i].confRev, SV_GET_LENGTH_INT32U);
sblair 0:230c10b228ea 116 //buf[offset++] = BER_GET_LENGTH_CTYPE_INT32U(&svData->ASDU[i].confRev);
sblair 0:230c10b228ea 117 //offset += BER_ENCODE_CTYPE_INT32U(&buf[offset], &svData->ASDU[i].confRev);
sblair 0:230c10b228ea 118
sblair 0:230c10b228ea 119 buf[offset++] = 0x85;
sblair 0:230c10b228ea 120 buf[offset++] = SV_GET_LENGTH_BOOLEAN;
sblair 0:230c10b228ea 121 offset += ENCODE_CTYPE_BOOLEAN(&buf[offset], &svData->ASDU[i].smpSynch);
sblair 0:230c10b228ea 122
sblair 0:230c10b228ea 123 /*buf[offset++] = 0x86;
sblair 0:230c10b228ea 124 buf[offset++] = SV_GET_LENGTH_INT16U;
sblair 0:230c10b228ea 125 offset += ENCODE_CTYPE_INT16U(&buf[offset], &svData->ASDU[i].smpRate);*/
sblair 0:230c10b228ea 126
sblair 0:230c10b228ea 127 buf[offset++] = 0x87;
sblair 0:230c10b228ea 128 offset += encodeLength(&buf[offset], svData->ASDU[i].data.size);
sblair 0:230c10b228ea 129 memcpy(&buf[offset], svData->ASDU[i].data.data, svData->ASDU[i].data.size);
sblair 0:230c10b228ea 130 offset += svData->ASDU[i].data.size;
sblair 0:230c10b228ea 131 }
sblair 0:230c10b228ea 132
sblair 0:230c10b228ea 133 // assume network interface, such as WinPcap, generates CRC bytes
sblair 0:230c10b228ea 134
sblair 0:230c10b228ea 135 return offset;
sblair 0:230c10b228ea 136 }