/* * Here start with callback functions that support the ZRTP core */ static int32_t zrtp_sendDataZRTP(ZrtpContext* ctx, const uint8_t* data, int32_t length) { struct tp_zrtp *zrtp = (struct tp_zrtp*)ctx->userData; pj_uint16_t totalLen = length + 12; /* Fixed number of bytes of ZRTP header */ pj_uint32_t crc; pj_uint8_t* buffer = zrtp->zrtpBuffer; pj_uint16_t* pus; pj_uint32_t* pui; if ((totalLen) > MAX_ZRTP_SIZE) return 0; /* Get some handy pointers */ pus = (pj_uint16_t*)buffer; pui = (pj_uint32_t*)buffer; /* set up fixed ZRTP header */ *buffer = 0x10; /* invalid RTP version - refer to ZRTP spec chap 5 */ *(buffer + 1) = 0; pus[1] = pj_htons(zrtp->zrtpSeq++); pui[1] = pj_htonl(ZRTP_MAGIC); pui[2] = pj_htonl(zrtp->localSSRC); /* stored in host order */ /* Copy ZRTP message data behind the header data */ pj_memcpy(buffer+12, data, length); /* Setup and compute ZRTP CRC */ crc = zrtp_GenerateCksum(buffer, totalLen-CRC_SIZE); /* convert and store CRC in ZRTP packet.*/ crc = zrtp_EndCksum(crc); *(uint32_t*)(buffer+totalLen-CRC_SIZE) = pj_htonl(crc); /* Send the ZRTP packet using the slave transport */ return (pjmedia_transport_send_rtp(zrtp->slave_tp, buffer, totalLen) == PJ_SUCCESS) ? 1 : 0; }
/** * Send a ZRTP packet via RTP. * * ZRTP calls this method to send a ZRTP packet via the RTP session. * * @param ctx * Pointer to the opaque ZrtpContext structure. * @param data * Points to ZRTP message to send. * @param length * The length in bytes of the data * @return * zero if sending failed, one if packet was sent */ static int32_t ozrtp_sendDataZRTP (ZrtpContext* ctx, const uint8_t* data, const int32_t length ){ OrtpZrtpContext *userData = user_data(ctx); RtpSession *session = userData->session; struct sockaddr *destaddr=(struct sockaddr*)&session->rtp.rem_addr; socklen_t destlen=session->rtp.rem_addrlen; ortp_socket_t sockfd=session->rtp.socket; // Create ZRTP packet int32_t newlength = length + 3*4; // strangely, given length includes CRC size !!!! uint32_t* buffer32 = alloca(newlength); uint8_t *buffer8=(uint8_t*)buffer32; uint16_t *buffer16=(uint16_t*)buffer32; uint16_t seqNumber=userData->last_sent_zrtp_seq_number++; *buffer8 = 0x10; buffer8[1]=0; buffer16[1] = htons(seqNumber); buffer32[1] = htonl(ZRTP_MAGIC); buffer32[2] = htonl(session->snd.ssrc); memcpy(buffer32+3, data, length); uint32_t cks=zrtp_EndCksum(zrtp_GenerateCksum(buffer8, newlength-CRC_SIZE)); buffer32[newlength/4-1] = htonl(cks); print_zrtp_packet("sent", buffer8); // Send packet ssize_t bytesSent = sendto(sockfd, (void*)buffer8, newlength,0,destaddr,destlen); if (bytesSent == -1 || bytesSent < length) { ortp_error("zrtp_sendDataZRTP: sent only %d bytes out of %d", (int)bytesSent, length); return 0; } else { return 1; } }