/* get the input text,and send it */ void send_text() { GtkTextIter start,end; gchar *text; if(issucceed==-1){ /* Haven't create a socket */ show_err("Not connected...\n"); } else { /* Socket creating has succeed ,so send message */ text=(gchar *)malloc(MAXSIZE); if(text==NULL) { printf("Malloc error!\n"); exit(1); } /* get text */ gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(input_buffer),&start,&end); text=gtk_text_buffer_get_text(GTK_TEXT_BUFFER(input_buffer),&start,&end,FALSE); /* If there is no input,do nothing but return */ if(strcmp(text,"")!=0) { send_func(text); clean_send_text(); show_local_text(text); } else show_err("The message can not be empty...\n"); free(text); } }
void OUTPUT_FORMATTER::process_text_buffer() { if (result_message_plain->strlen() > 0) { send_func(send_ctx, result_message_plain->c_str()); result_message_plain->strcpy(""); } }
void OUTPUT_FORMATTER::json_finalize_result(bool result) { POOL_MEM string; json_t *msg_obj = json_object(); json_t *error_obj; /* * We mimic json-rpc result and error messages, * To make it easier to implement real json-rpc later on. */ json_object_set(msg_obj, "jsonrpc", json_string("2.0")); json_object_set(msg_obj, "id", json_null()); if (result) { json_object_set(msg_obj, "result", result_array_json); } else { error_obj = json_object(); json_object_set_new(error_obj, "code", json_integer(1)); json_object_set_new(error_obj, "message", json_string("failed")); json_object_set(error_obj, "data", result_array_json); json_object_set_new(msg_obj, "error", error_obj); } string.bsprintf("%s\n", json_dumps(msg_obj, UA_JSON_FLAGS)); send_func(send_ctx, string.c_str()); json_array_clear(result_array_json); json_object_clear(msg_obj); }
int client_add(struct IPC_CHANNEL *ipc_client) { ccm_client_t *ccm_client; if(!ccm_hashclient) { ccm_log(LOG_ERR, "client subsystem not initialized"); return -1; } ccm_client = (ccm_client_t *) g_malloc(sizeof(ccm_client_t)); ccm_client->ccm_clid = 0; /* don't care, TOBEDONE */ ccm_client->ccm_ipc_client = ipc_client; ccm_client->ccm_flags = CL_INIT; send_func(ipc_client, ccm_client, (gpointer)CCM_NEW_MEMBERSHIP); g_hash_table_insert(ccm_hashclient, ipc_client, ccm_client); return 0; }
int tcpsendfile_ex(int sock, const char *filename, const int64_t file_offset, \ const int64_t file_bytes, const int timeout, int64_t *total_send_bytes) { int fd; int64_t send_bytes; int result; int flags; #ifdef USE_SENDFILE #if defined(OS_FREEBSD) || defined(OS_LINUX) off_t offset; #ifdef OS_LINUX int64_t remain_bytes; #endif #endif #else int64_t remain_bytes; #endif fd = open(filename, O_RDONLY); if (fd < 0) { *total_send_bytes = 0; return errno != 0 ? errno : EACCES; } flags = fcntl(sock, F_GETFL, 0); if (flags < 0) { *total_send_bytes = 0; return errno != 0 ? errno : EACCES; } #ifdef USE_SENDFILE if (flags & O_NONBLOCK) { if (fcntl(sock, F_SETFL, flags & ~O_NONBLOCK) == -1) { *total_send_bytes = 0; return errno != 0 ? errno : EACCES; } } #ifdef OS_LINUX /* result = 1; if (setsockopt(sock, SOL_TCP, TCP_CORK, &result, sizeof(int)) < 0) { logError("file: "__FILE__", line: %d, " \ "setsockopt failed, errno: %d, error info: %s.", \ __LINE__, errno, STRERROR(errno)); close(fd); *total_send_bytes = 0; return errno != 0 ? errno : EIO; } */ #define FILE_1G_SIZE (1 * 1024 * 1024 * 1024) result = 0; offset = file_offset; remain_bytes = file_bytes; while (remain_bytes > 0) { if (remain_bytes > FILE_1G_SIZE) { send_bytes = sendfile(sock, fd, &offset, FILE_1G_SIZE); } else { send_bytes = sendfile(sock, fd, &offset, remain_bytes); } if (send_bytes <= 0) { result = errno != 0 ? errno : EIO; break; } remain_bytes -= send_bytes; } *total_send_bytes = file_bytes - remain_bytes; #else #ifdef OS_FREEBSD offset = file_offset; if (sendfile(fd, sock, offset, file_bytes, NULL, NULL, 0) != 0) { *total_send_bytes = 0; result = errno != 0 ? errno : EIO; } else { *total_send_bytes = file_bytes; result = 0; } #endif #endif if (flags & O_NONBLOCK) //restore { if (fcntl(sock, F_SETFL, flags) == -1) { result = errno != 0 ? errno : EACCES; } } #ifdef OS_LINUX close(fd); return result; #endif #ifdef OS_FREEBSD close(fd); return result; #endif #endif { char buff[FDFS_WRITE_BUFF_SIZE]; int64_t remain_bytes; tcpsenddatafunc send_func; if (file_offset > 0 && lseek(fd, file_offset, SEEK_SET) < 0) { result = errno != 0 ? errno : EIO; close(fd); *total_send_bytes = 0; return result; } if (flags & O_NONBLOCK) { send_func = tcpsenddata_nb; } else { send_func = tcpsenddata; } result = 0; remain_bytes = file_bytes; while (remain_bytes > 0) { if (remain_bytes > sizeof(buff)) { send_bytes = sizeof(buff); } else { send_bytes = remain_bytes; } if (read(fd, buff, send_bytes) != send_bytes) { result = errno != 0 ? errno : EIO; break; } if ((result=send_func(sock, buff, send_bytes, \ timeout)) != 0) { break; } remain_bytes -= send_bytes; } *total_send_bytes = file_bytes - remain_bytes; } close(fd); return result; }
/** * Send a packet using the set send function. * * @param data * The packet data. * * @param len * The data length. */ void bldc_interface_send_packet(unsigned char *data, unsigned int len) { if (send_func) { send_func(data, len); } }
/** * Send a packet using the set send function. * * @param data * The packet data. * * @param len * The data length. */ void commands_send_packet(unsigned char *data, unsigned int len) { if (send_func) { send_func(data, len); } }
void* recv_func(void* unusedParam) { int numbytes; char* buf = (char*)malloc(sizeof(header) + MAXBUFLEN); while((numbytes = recvfrom(s, buf, sizeof(header) + MAXBUFLEN, 0, (struct sockaddr *)&other, &len)) > 0) { header* sendHeader = (header*)buf; if(sendHeader->Flags == 'I' || totalNumBytes == 0) { header* SHeader = (header*)malloc(sizeof(header)); SHeader->Flags = 'S'; if(sendto(s, SHeader, sizeof(header), 0, (struct sockaddr *)&other, len) <= 0) { perror("reply initial"); } totalNumBytes = *((long*)(buf + sizeof(header))); totalFrame = totalNumBytes % MAXBUFLEN == 0? totalNumBytes / MAXBUFLEN : totalNumBytes / MAXBUFLEN + 1; lastFrameSize = totalNumBytes % MAXBUFLEN; if(lastFrameSize == 0) { lastFrameSize = MAXBUFLEN; } ////printf("lastFrameSize %lu\n", lastFrameSize); ////printf("totalNumBytes: %lu totalframe %lu lastframe %lu\n", totalNumBytes, totalFrame, lastFrameSize); continue; } else if(sendHeader->Flags == 'D') { ////printf("numbytes %d Recvbuf %s\n", numbytes, buf + sizeof(header)); //printf("Recv seqnum %lu, NBE %lu\n", sendHeader->SeqNum, NBE->SeqNum); if(sendHeader->SeqNum == NBE->SeqNum) { pthread_mutex_lock(&recv_m); NBE->status = 1; NBE->sendBuf = (char*)malloc(sendHeader->SeqNum == totalFrame? lastFrameSize : MAXBUFLEN); memcpy(NBE->sendBuf, buf + sizeof(header), sendHeader->SeqNum == totalFrame? lastFrameSize : MAXBUFLEN); while(NBE->status == 1) { AckNum++; //printf("ACK num %lu\n", AckNum); if(NBE->next == NULL) { NBE->next = (slot*)malloc(sizeof(slot)); NBE->next->sendBuf = NULL; NBE->next->SeqNum = NBE->SeqNum + 1; NBE->next->next = NULL; } NBE = NBE->next; } if(NBE->SeqNum == totalFrame + 1) { isFinished = 1; } pthread_mutex_unlock(&recv_m); pthread_cond_broadcast(&recv_cv); send_func(AckNum, 0); } else if(sendHeader->SeqNum > NBE->SeqNum) { int i; int shouldgo = 0; if(LSA == NULL) { LSA = NBE; shouldgo = 1; } slot* current = NBE; if(sendHeader->SeqNum <= LSA->SeqNum || shouldgo) { //printf("sender seq %lu, NBE seq %lu LSA seq %lu\n", sendHeader->SeqNum, NBE->SeqNum, LSA->SeqNum); printf("Packet lost, leap \n"); for(i = 0; i < sendHeader->SeqNum - NBE->SeqNum; i++) { if(current->next == NULL) { current->next = (slot*)malloc(sizeof(slot)); current->next->next = NULL; current->next->SeqNum = current->SeqNum + 1; printf("malloc for %lu %p\n", current->SeqNum + 1, current->next); current->next->sendBuf = NULL; ////printf("hole recieve, seqnum %lu\n", SeqNum); } current = current->next; } shouldgo = 0; } else { current = LSA; for(i = 0; i < sendHeader->SeqNum - LSA->SeqNum; i++) { if(current->next == NULL) { current->next = (slot*)malloc(sizeof(slot)); current->next->next = NULL; current->next->SeqNum = current->SeqNum + 1; //printf("malloc for %lu %p LSA %lu\n", current->SeqNum + 1, current->next, LSA->SeqNum); current->next->sendBuf = NULL; ////printf("hole recieve, seqnum %lu\n", SeqNum); } current = current->next; } LSA = current; } current->status = 1; //printf("current seq %lu sendseq %lu\n", current->SeqNum, sendHeader->SeqNum); //printf("current %lu, recv Seq %lu\n", current->SeqNum, sendHeader->SeqNum); current->sendBuf = (char*)malloc(sendHeader->SeqNum == totalFrame? lastFrameSize : MAXBUFLEN); ////printf("lastFrameSize %lu\n", lastFrameSize); memcpy(current->sendBuf, buf + sizeof(header), sendHeader->SeqNum == totalFrame? lastFrameSize : MAXBUFLEN); send_func(AckNum, 1); } else { send_func(sendHeader->SeqNum, 1); } } else if(sendHeader->Flags == 'F') { //printf("receive FIN\n"); header* replyHeader = (header*)malloc(sizeof(header)); replyHeader->Flags = 'R'; int i = 0; for(i = 0; i < 5; i++) { if((numbytes = sendto(s, replyHeader, sizeof(header), 0, (struct sockaddr *)&other, len)) <= 0) { perror("reply finish"); } } free(replyHeader); free(buf); pthread_cond_broadcast(&recv_cv); //printf("recv thread exit\n"); return NULL; } } }
/** @brief This function is called when a new EIT packet for a channel is there and we asked for rewrite * This function copy the rewritten EIT to the buffer. And checks if the EIT was changed so the rewritten version have to be updated */ void eit_rewrite_new_channel_packet(unsigned char *ts_packet, rewrite_parameters_t *rewrite_vars, mumudvb_channel_t *channel, multicast_parameters_t *multicast_vars, unicast_parameters_t *unicast_vars, mumudvb_chan_and_pids_t *chan_and_pids,fds_t *fds) { int i=0; //If payload unit start indicator , we will send all the present EIT for this service, otherwise nothing //We generate the TS packets on by one, and for each one, we check if we have to send //Otherwise we skip the packet //If payload unit start indicator, we will send all the present EIT for this service, otherwise nothing //just a matter to send an EIT per service only if an EIT is starting in the stream, //the better way would be an EIT starting and corresponding to this SID but, it's more difficult to get this information ts_header_t *ts_header=(ts_header_t *)ts_packet; if(!(ts_header->payload_unit_start_indicator)) return; //If there is an EIT PID sorted for this channel eit_packet_t *eit_pkt; eit_pkt=eit_find_by_tsid(rewrite_vars,channel->service_id); if((eit_pkt==NULL)||(!eit_pkt->full_eit_ok)) return; //search for the next section we can send //just in case we have a new version with less sections channel->eit_section_to_send=channel->eit_section_to_send % (eit_pkt->last_section_number+1); //the real search while((i<=eit_pkt->last_section_number)&&(!eit_pkt->sections_stored[channel->eit_section_to_send])) { channel->eit_section_to_send++; channel->eit_section_to_send=channel->eit_section_to_send % (eit_pkt->last_section_number+1); i++; } //if nothing found if(!eit_pkt->sections_stored[channel->eit_section_to_send]) return; //bye //ok we send this! mumudvb_ts_packet_t *pkt_to_send; int data_left_to_send,sent; unsigned char send_buf[TS_PACKET_SIZE]; ts_header=(ts_header_t *)send_buf; pkt_to_send=eit_pkt->full_eit_sections[channel->eit_section_to_send]; data_left_to_send=pkt_to_send->full_buffer_len; sent=0; //log_message(log_module,MSG_FLOOD,"Sending EIT to channel %s (sid %d) section %d data_len %d", // channel->name, // channel->service_id, // channel->eit_section_to_send, // data_left_to_send); while(data_left_to_send>0) { int header_len; memset(send_buf,0,TS_PACKET_SIZE*sizeof(unsigned char)); //we fill the TS header ts_header->sync_byte=0x47; if(sent==0) { ts_header->payload_unit_start_indicator=1; header_len=TS_HEADER_LEN; //includes the pointer field } else header_len=TS_HEADER_LEN-1; //the packet has started, we don't count the pointer field ts_header->pid_lo=18; //specify the PID ts_header->adaptation_field_control=1; //always one ts_header->continuity_counter=channel->eit_cc; //continuity counter channel->eit_cc++; channel->eit_cc= channel->eit_cc % 16; //We send the data //plus one because of pointer field if(data_left_to_send>(TS_PACKET_SIZE-header_len)) { memcpy(send_buf+header_len,pkt_to_send->data_full+sent,(TS_PACKET_SIZE-header_len)*sizeof(unsigned char)); sent+=(TS_PACKET_SIZE-header_len); data_left_to_send-=(TS_PACKET_SIZE-header_len); } else { memcpy(send_buf+header_len,pkt_to_send->data_full+sent,data_left_to_send*sizeof(unsigned char)); sent+=data_left_to_send; //Padding with OxFF memset(send_buf+header_len+data_left_to_send, 0xFF, (TS_PACKET_SIZE-(header_len+data_left_to_send))*sizeof(unsigned char)); data_left_to_send=0; } //NOW we really send the data over the network // we fill the channel buffer memcpy(channel->buf + channel->nb_bytes, send_buf, TS_PACKET_SIZE*sizeof(unsigned char)); channel->nb_bytes += TS_PACKET_SIZE; //The buffer is full, we send it if ((!multicast_vars->rtp_header && ((channel->nb_bytes + TS_PACKET_SIZE) > MAX_UDP_SIZE)) ||(multicast_vars->rtp_header && ((channel->nb_bytes + RTP_HEADER_LEN + TS_PACKET_SIZE) > MAX_UDP_SIZE))) { uint64_t now_time; now_time=get_time(); send_func(channel, &now_time, unicast_vars, multicast_vars, chan_and_pids, fds); } } //We update which section we want to send channel->eit_section_to_send++; channel->eit_section_to_send=channel->eit_section_to_send % (eit_pkt->last_section_number+1); //TODO increase table id if we reached the end }
void *sendthread_func(void* arg) { int pid; /** pid of the current mpeg2 packet */ int ScramblingControl; int curr_pid = 0; int send_packet = 0; extern unicast_parameters_t unicast_vars; extern multi_p_t multi_p; extern int dont_send_scrambled; extern fds_t fds; mumudvb_channel_t *channel; channel = ((mumudvb_channel_t *) arg); uint64_t res_time; struct timespec r_time; int first_run = 1; while(!channel->sendthread_shutdown) { int to_send; pthread_mutex_lock(&channel->ring_buf->lock); to_send = channel->ring_buf->to_send; pthread_mutex_unlock(&channel->ring_buf->lock); if (to_send) break; else usleep(50000); } while(!channel->sendthread_shutdown) { pthread_mutex_lock(&channel->ring_buf->lock); uint64_t now_time=get_time(); uint64_t send_time = channel->ring_buf->time_send[channel->ring_buf->read_send_idx]; int to_descramble = channel->ring_buf->to_descramble; int to_send = channel->ring_buf->to_send; pthread_mutex_unlock(&channel->ring_buf->lock); if (to_send == 0) { if (first_run) { first_run = 0; log_message( log_module, MSG_DEBUG, "first run waiting"); } else log_message( log_module, MSG_ERROR, "thread starved, channel %s %u %u\n",channel->name,to_descramble,to_send); usleep(50000); continue; } if (now_time < send_time) { res_time=send_time - now_time; r_time.tv_sec=res_time/(1000000ull); r_time.tv_nsec=1000*(res_time%(1000000ull)); while(nanosleep(&r_time, &r_time)); } pthread_mutex_lock(&channel->ring_buf->lock); pid = ((channel->ring_buf->data[channel->ring_buf->read_send_idx][1] & 0x1f) << 8) | (channel->ring_buf->data[channel->ring_buf->read_send_idx][2]); ScramblingControl = (channel->ring_buf->data[channel->ring_buf->read_send_idx][3] & 0xc0) >> 6; pthread_mutex_lock(&channel->stats_lock); for (curr_pid = 0; (curr_pid < channel->num_pids); curr_pid++) if ((channel->pids[curr_pid] == pid) || (channel->pids[curr_pid] == 8192)) //We can stream whole transponder using 8192 { if ((ScramblingControl>0) && (pid != channel->pmt_pid) ) channel->num_scrambled_packets++; //check if the PID is scrambled for determining its state if (ScramblingControl>0) channel->pids_num_scrambled_packets[curr_pid]++; //we don't count the PMT pid for up channels if (pid != channel->pmt_pid) channel->num_packet++; break; } pthread_mutex_unlock(&channel->stats_lock); //avoid sending of scrambled channels if we asked to send_packet=1; if(dont_send_scrambled && (ScramblingControl>0)&& (channel->pmt_pid) ) send_packet=0; if (send_packet) { // we fill the channel buffer memcpy(channel->buf + channel->nb_bytes, channel->ring_buf->data[channel->ring_buf->read_send_idx], TS_PACKET_SIZE); channel->nb_bytes += TS_PACKET_SIZE; } ++channel->ring_buf->read_send_idx; channel->ring_buf->read_send_idx&=(channel->ring_buffer_size -1); --channel->ring_buf->to_send; pthread_mutex_unlock(&channel->ring_buf->lock); //The buffer is full, we send it if ((!multi_p.rtp_header && ((channel->nb_bytes + TS_PACKET_SIZE) > MAX_UDP_SIZE)) ||(multi_p.rtp_header && ((channel->nb_bytes + RTP_HEADER_LEN + TS_PACKET_SIZE) > MAX_UDP_SIZE))) { send_func(channel, send_time, &unicast_vars, &multi_p, &fds); } } return 0; }
/** @brief function for buffering demultiplexed data. */ void buffer_func (mumudvb_channel_t *channel, unsigned char *ts_packet, struct unicast_parameters_t *unicast_vars, multi_p_t *multi_p, void *scam_vars_v, fds_t *fds) { int pid; /** pid of the current mpeg2 packet */ int ScramblingControl; int curr_pid = 0; int send_packet = 0; extern int dont_send_scrambled; #ifndef ENABLE_SCAM_SUPPORT (void) scam_vars_v; //to make compiler happy #else scam_parameters_t *scam_vars=(scam_parameters_t *)scam_vars_v; #endif uint64_t now_time; #ifdef ENABLE_SCAM_SUPPORT if (channel->scam_support && scam_vars->scam_support) { pthread_mutex_lock(&channel->ring_buf->lock); memcpy(channel->ring_buf->data+TS_PACKET_SIZE*channel->ring_buf->write_idx, ts_packet, TS_PACKET_SIZE); now_time=get_time(); channel->ring_buf->time_send[channel->ring_buf->write_idx]=now_time + channel->send_delay; channel->ring_buf->time_decsa[channel->ring_buf->write_idx]=now_time + channel->decsa_delay; ++channel->ring_buf->write_idx; channel->ring_buf->write_idx&=(channel->ring_buffer_size -1); ++channel->ring_buf->to_descramble; pthread_mutex_unlock(&channel->ring_buf->lock); } else #endif { pid = ((ts_packet[1] & 0x1f) << 8) | (ts_packet[2]); ScramblingControl = (ts_packet[3] & 0xc0) >> 6; pthread_mutex_lock(&channel->stats_lock); for (curr_pid = 0; (curr_pid < channel->num_pids); curr_pid++) if ((channel->pids[curr_pid] == pid) || (channel->pids[curr_pid] == 8192)) //We can stream whole transponder using 8192 { if ((ScramblingControl>0) && (pid != channel->pmt_pid) ) channel->num_scrambled_packets++; //check if the PID is scrambled for determining its state if (ScramblingControl>0) channel->pids_num_scrambled_packets[curr_pid]++; //we don't count the PMT pid for up channels if (pid != channel->pmt_pid) channel->num_packet++; break; } pthread_mutex_unlock(&channel->stats_lock); //avoid sending of scrambled channels if we asked to send_packet=1; if(dont_send_scrambled && (ScramblingControl>0)&& (channel->pmt_pid) ) send_packet=0; if (send_packet) { // we fill the channel buffer memcpy(channel->buf + channel->nb_bytes, ts_packet, TS_PACKET_SIZE); channel->nb_bytes += TS_PACKET_SIZE; } //The buffer is full, we send it if ((!multi_p->rtp_header && ((channel->nb_bytes + TS_PACKET_SIZE) > MAX_UDP_SIZE)) ||(multi_p->rtp_header && ((channel->nb_bytes + RTP_HEADER_LEN + TS_PACKET_SIZE) > MAX_UDP_SIZE))) { now_time=get_time(); send_func(channel, now_time, unicast_vars, multi_p, fds); } } }
static void send_packet(unsigned char *data, unsigned char len) { if (send_func) { send_func(data, len); } }
int vid_cmd_proc(tcpc_t c) { struct wcamcli *wc = c->arg; struct vid *v = wc->srv->vid; __u8 *req = wc->req; __u8 *rsp = wc->rsp; __u8 id = req[CMD1_POS]; __u8 status = ERR_SUCCESS; __u8 dat[FRAME_DAT_MAX]; __u32 pos, len, size; switch (id) { case REQUEST_ID(VID_GET_UCTL): vid_get_uctl(v, &req[DAT_POS], dat); build_and_send_rsp(c, (TYPE_SRSP << TYPE_BIT_POS) | SUBS_VID, id, 4, dat); break; case REQUEST_ID(VID_GET_UCTLS): /* * 应答帧结构: 字节 / 字段名称 * 1 | 2 | 4 | 长度由4字节数据部分指定 * 长度 | 命令 | 数据(控制项列表大小) | 控制项列表 */ len = sizeof(__u32); pos = FRAME_HDR_SZ + len; size = vid_get_uctls(v, &rsp[pos]); build_rsp(rsp, (TYPE_SRSP << TYPE_BIT_POS) | SUBS_VID, id, len, (__u8*)&size); tcpc_send(c, rsp, pos + size); break; case REQUEST_ID(VID_SET_UCTL): vid_set_uctl(v, &req[DAT_POS]); break; case REQUEST_ID(VID_SET_UCS2DEF): v4l2_set_uctls2def(v->cam); break; case REQUEST_ID(VID_GET_FMT): vid_get_fmt(v, dat); build_and_send_rsp(c, (TYPE_SRSP << TYPE_BIT_POS) | SUBS_VID, id, 4, dat); break; case REQUEST_ID(VID_GET_FRMSIZ): vid_get_frmsiz(v, dat); build_and_send_rsp(c, (TYPE_SRSP << TYPE_BIT_POS) | SUBS_VID, id, 8, dat); break; #if 0 case REQUEST_ID(VID_GET_FMTS): /* * 应答帧结构: 字节 / 字段名称 * 1 | 2 | 4 | 长度由4字节数据部分指定 * 长度 | 命令 | 数据(格式分辨率列表大小) | 格式分辨率列表 */ len = sizeof(__u32); pos = FRAME_HDR_SZ + len; size = vid_get_fmts(v, &rsp[pos]); build_rsp(rsp, (TYPE_SRSP << TYPE_BIT_POS) | SUBS_VID, id, len, (__u8*)&size); send_func(c, rsp, pos + size); break; case REQUEST_ID(VID_SET_FMT): vid_set_fmt(v, &req[DAT_POS]); break; #endif case REQUEST_ID(VID_REQ_FRAME): /* * 应答帧结构: 字节 / 字段名称 * 1 | 2 | 4 | 长度由4字节数据部分指定 * 长度 | 命令 | 数据(图像帧大小) | 图像帧 */ len = sizeof(__u32); pos = FRAME_HDR_SZ + len; pthread_mutex_lock(&v->tran_frm_mutex); if (v->tran_frm_index != wc->last_frm_index) { size = vid_get_trans_frame(v, &rsp[pos]); wc->last_frm_index = v->tran_frm_index; } else { size = 0; } pthread_mutex_unlock(&v->tran_frm_mutex); build_rsp(rsp, (TYPE_SRSP << TYPE_BIT_POS) | SUBS_VID, id, len, (__u8*)&size); tcpc_send(c, rsp, pos + size); break; default: status = ERR_CMD_ID; break; } return status; }
/* * scamper_probe_send * * this meta-function is responsible for * 1. sending a probe * 2. handling any error condition incurred when sending the probe * 3. recording details of the probe with the trace's state */ int scamper_probe(scamper_probe_t *probe) { int (*send_func)(scamper_probe_t *) = NULL; int (*build_func)(scamper_probe_t *, uint8_t *, size_t *) = NULL; size_t pad, len; uint8_t *buf; probe->pr_errno = 0; probe_print(probe); /* determine which function scamper should use to build or send the probe */ if(probe->pr_ip_dst->type == SCAMPER_ADDR_TYPE_IPV4) { if((probe->pr_ip_off & IP_OFFMASK) != 0) { build_func = scamper_ip4_frag_build; } else if(probe->pr_ip_proto == IPPROTO_UDP) { send_func = scamper_udp4_probe; build_func = scamper_udp4_build; } else if(probe->pr_ip_proto == IPPROTO_TCP) { build_func = scamper_tcp4_build; if(probe->pr_fd != -1) send_func = scamper_tcp4_probe; } else if(probe->pr_ip_proto == IPPROTO_ICMP) { send_func = scamper_icmp4_probe; build_func = scamper_icmp4_build; } } else if(probe->pr_ip_dst->type == SCAMPER_ADDR_TYPE_IPV6) { if(probe->pr_ip_off != 0) { build_func = scamper_ip6_frag_build; } else if(probe->pr_ip_proto == IPPROTO_UDP) { send_func = scamper_udp6_probe; build_func = scamper_udp6_build; } else if(probe->pr_ip_proto == IPPROTO_TCP) { build_func = scamper_tcp6_build; } else if(probe->pr_ip_proto == IPPROTO_ICMPV6) { send_func = scamper_icmp6_probe; build_func = scamper_icmp6_build; } } /* if we're not using the datalink to send the packet, then send it now */ if(probe->pr_dl == NULL) { if(send_func != NULL) return send_func(probe); probe->pr_errno = EINVAL; return -1; } /* if the header type is not known (we cannot build it) then bail */ if(build_func == NULL) { probe->pr_errno = EINVAL; return -1; } /* * determine a suitable value for the length parameter for passing * to build_func. to do so we also need to calculate the number of pad * bytes to put at the front of the packet buffer so that the IP layer * is properly aligned for the architecture */ pad = PAD(probe->pr_dl_len); if(pad + probe->pr_dl_len >= pktbuf_len) len = 0; else len = pktbuf_len - pad - probe->pr_dl_len; /* * try building the probe. if it returns -1, then hopefully the len field * will supply a clue as to what it should be */ if(build_func(probe, pktbuf + pad + probe->pr_dl_len, &len) != 0) { assert(pktbuf_len < pad + probe->pr_dl_len + len); /* reallocate the packet buffer */ len += pad + probe->pr_dl_len; if((buf = realloc(pktbuf, len)) == NULL) { probe->pr_errno = errno; printerror(errno, strerror, __func__, "could not realloc"); return -1; } pktbuf = buf; pktbuf_len = len; len = pktbuf_len - pad - probe->pr_dl_len; if(build_func(probe, pktbuf + pad + probe->pr_dl_len, &len) != 0) { probe->pr_errno = EINVAL; return -1; } } /* add the datalink header size back to the length field */ len += probe->pr_dl_len; /* pre-pend the datalink header, if there is one */ if(probe->pr_dl_len > 0) memcpy(pktbuf+pad, probe->pr_dl_buf, probe->pr_dl_len); gettimeofday_wrap(&probe->pr_tx); if(scamper_dl_tx(probe->pr_dl, pktbuf+pad, len) == -1) { probe->pr_errno = errno; return -1; } probe->pr_tx_raw = pktbuf + pad + probe->pr_dl_len; probe->pr_tx_rawlen = len - probe->pr_dl_len; return 0; }