int sendChunkedMessage(xentoollog_logger * xc_logger, struct libxenvchan * txCtrl, char * msg, int size ) { int headerSize = 8; int maxSize = 1024; int availSize = maxSize - headerSize; char *buf = 0; char *chunk; int writeSize = 0; int result = 0; int i = 0; int idx = 0; int n = 1; //If this fails we need to change the header size to have more digits if ( size > 9999999){ fprintf(stderr, "Message size was too large (maxSize: (%d), will need to change the header size to send a message of that size: %d\n",9999999, size); perror("sendChunkedMessage: send failed."); exit(1); } //We can send a maximum of 1024, do we need to send the message in chunks? if (size > availSize){ buf = (char*)malloc(sizeof(char) * maxSize); if ( buf == NULL){ fprintf(stderr, "Error: Failed to allocate space for buffer\n"); perror("sendChunkedMessage: send failed."); exit(1); } buf[0] = (char) 255; //chunked sprintf(buf+1,"%7d",size); sprintf(buf+headerSize,"%7d", availSize-headerSize+1); memcpy(buf+(2*headerSize -1),msg,(maxSize - (2*headerSize -1))); // Can send the entire message }else{ buf = (char *)malloc(size * sizeof(char)+ sizeof(char) * (2*headerSize -1)); if ( buf == NULL){ fprintf(stderr, "Error: Failed to allocate space for buffer\n"); perror("sendChunkedMessage: send failed."); exit(1); } buf[0] = (char) 254; // not chunked sprintf(buf+1,"%7d",size); memcpy(buf+headerSize,msg,size); /* printf("HexDump\n"); for (i = 0; i < size+headerSize;i++){ printf("%2x ",buf[i]); } printf("\n"); */ } //chunk if (size > availSize){ /* printf("HexDump\n"); for (i = 0; i < maxSize;i++){ printf("%2x ",buf[i]); } printf("\n"); */ // chunked totalsize payloadSize payload // loop until we have enough space while(libxenvchan_buffer_space(txCtrl) <maxSize){ sleep(0.1); } writeSize = libxenvchan_write(txCtrl,buf,maxSize); free(buf); n++; idx+=availSize-headerSize+1; chunk = (char*)malloc(sizeof(char) * maxSize); if ( chunk == NULL){ fprintf(stderr, "Error: Failed to allocate space for buffer\n"); perror("sendChunkedMessage: send failed."); exit(1); } chunk[0] = (char) 255; sprintf(chunk+1,"%7d",availSize); for ( i = 1; i < (size/availSize);i++){ memcpy(chunk+headerSize, msg+(idx), availSize); idx+=availSize; /* printf("Chunk\n"); for (j = 0; j < maxSize;j++){ printf("%2x ",chunk[j]); } printf("\n"); */ //wait until there is enough space while(libxenvchan_buffer_space(txCtrl) < maxSize){ sleep(0.1); // printf("Waiting for space to write\n"); } //send chunk writeSize += libxenvchan_write(txCtrl,chunk, maxSize); n++; } //send leftover chunk // printf("Sending Leftover chunk\n"); sprintf(chunk+1,"%7d", size-idx); memcpy(chunk+headerSize, msg+(idx),size -idx); /* for (j = 0; j < size -idx + headerSize; j++){ printf("%2x ",chunk[j]); } printf("\n"); */ while(libxenvchan_buffer_space(txCtrl) < maxSize){ sleep(0.1); // printf("Waiting for space to write\n"); } writeSize+= libxenvchan_write(txCtrl,chunk,size-idx+headerSize ); free(chunk); //no chunk }else{ while(libxenvchan_buffer_space(txCtrl) < maxSize){ sleep(0.1); // printf("Waiting for space to write\n"); } writeSize = libxenvchan_write(txCtrl, buf, size+headerSize); free(buf); } if (writeSize < 0) { perror("vchan to serverExp1 write"); exit(1); } if (writeSize == 0) { perror("write serverExp1 size=0?"); exit(1); } if (writeSize != size+(n*headerSize)+7) { fprintf(stdout,"wrote %d totalsize %d\n",writeSize,size+(n*headerSize)+7); // perror("write writeExp1 failed to write whole buffer."); // exit(1); } return result; }
int libvchan_write(libvchan_t *ctrl, const void *data, size_t size) { return libxenvchan_write(ctrl->xenvchan, (char*)data, size); }