2 * Copyright (C) ARM Limited 2010-2014. All rights reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
17 #include "OlySocket.h"
18 #include "SessionData.h"
20 Sender::Sender(OlySocket* socket) {
24 // Set up the socket connection
26 char streamline[64] = {0};
29 // Receive magic sequence - can wait forever
30 // Streamline will send data prior to the magic sequence for legacy support, which should be ignored for v4+
31 while (strcmp("STREAMLINE", streamline) != 0) {
32 if (mDataSocket->receiveString(streamline, sizeof(streamline)) == -1) {
33 logg->logError(__FILE__, __LINE__, "Socket disconnected");
38 // Send magic sequence - must be done first, after which error messages can be sent
40 snprintf(magic, 32, "GATOR %i\n", PROTOCOL_VERSION);
41 mDataSocket->send(magic, strlen(magic));
43 gSessionData->mWaitingOnCommand = true;
44 logg->logMessage("Completed magic sequence");
47 pthread_mutex_init(&mSendMutex, NULL);
51 // Just close it as the client socket is on the stack
52 if (mDataSocket != NULL) {
53 mDataSocket->closeSocket();
56 if (mDataFile != NULL) {
61 void Sender::createDataFile(char* apcDir) {
66 mDataFileName = (char*)malloc(strlen(apcDir) + 12);
67 sprintf(mDataFileName, "%s/0000000000", apcDir);
68 mDataFile = fopen(mDataFileName, "wb");
70 logg->logError(__FILE__, __LINE__, "Failed to open binary file: %s", mDataFileName);
76 inline T min(const T a, const T b) {
77 return (a < b ? a : b);
80 void Sender::writeData(const char* data, int length, int type) {
81 if (length < 0 || (data == NULL && length > 0)) {
85 // Multiple threads call writeData()
86 pthread_mutex_lock(&mSendMutex);
88 // Send data over the socket connection
91 const int alarmDuration = 8;
94 // Send data over the socket, sending the type and size first
95 logg->logMessage("Sending data with length %d", length);
96 if (type != RESPONSE_APC_DATA) {
97 // type and length already added by the Collector for apc data
98 unsigned char header[5];
100 Buffer::writeLEInt(header + 1, length);
101 mDataSocket->send((char*)&header, sizeof(header));
104 // 100Kbits/sec * alarmDuration sec / 8 bits/byte
105 const int chunkSize = 100*1000 * alarmDuration / 8;
108 mDataSocket->send((const char*)data + pos, min(length - pos, chunkSize));
115 alarm(alarmDuration);
116 logg->logMessage("Resetting the alarm");
123 // Write data to disk as long as it is not meta data
124 if (mDataFile && type == RESPONSE_APC_DATA) {
125 logg->logMessage("Writing data with length %d", length);
126 // Send data to the data file
127 if (fwrite(data, 1, length, mDataFile) != (unsigned int)length) {
128 logg->logError(__FILE__, __LINE__, "Failed writing binary file %s", mDataFileName);
133 pthread_mutex_unlock(&mSendMutex);