Lines Matching defs:state

124   tftp_state_t    state;
148 static CURLcode tftp_rx(struct tftp_state_data *state, tftp_event_t event);
149 static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event);
197 * Set timeouts based on state machine state.
203 static CURLcode tftp_set_timeouts(struct tftp_state_data *state)
207 bool start = (state->state == TFTP_STATE_START) ? TRUE : FALSE;
210 timeout_ms = Curl_timeleft(state->data, NULL, start);
214 failf(state->data, "Connection time-out");
227 state->retry_max = (int)timeout/5;
230 if(state->retry_max<3)
231 state->retry_max = 3;
233 if(state->retry_max>50)
234 state->retry_max = 50;
237 state->retry_time = (int)(timeout/state->retry_max);
238 if(state->retry_time<1)
239 state->retry_time = 1;
241 infof(state->data,
242 "set timeouts for state %d; Total % " CURL_FORMAT_CURL_OFF_T
244 (int)state->state, timeout_ms, state->retry_time, state->retry_max);
247 time(&state->rx_time);
256 * Event handler for the START state
311 static CURLcode tftp_parse_option_ack(struct tftp_state_data *state,
315 struct Curl_easy *data = state->data;
318 state->blksize = TFTP_BLKSIZE_DEFAULT;
350 else if(blksize > state->requested_blksize) {
359 state->blksize = (int)blksize;
361 state->blksize, "requested", state->requested_blksize);
371 if(!data->state.upload) {
384 static CURLcode tftp_option_add(struct tftp_state_data *state, size_t *csize,
387 if(( strlen(option) + *csize + 1) > (size_t)state->blksize)
394 static CURLcode tftp_connect_for_tx(struct tftp_state_data *state,
399 struct Curl_easy *data = state->data;
403 state->state = TFTP_STATE_TX;
404 result = tftp_set_timeouts(state);
407 return tftp_tx(state, event);
410 static CURLcode tftp_connect_for_rx(struct tftp_state_data *state,
415 struct Curl_easy *data = state->data;
419 state->state = TFTP_STATE_RX;
420 result = tftp_set_timeouts(state);
423 return tftp_rx(state, event);
426 static CURLcode tftp_send_first(struct tftp_state_data *state,
433 struct Curl_easy *data = state->data;
437 if(data->state.prefer_ascii)
445 state->retries++;
446 if(state->retries>state->retry_max) {
447 state->error = TFTP_ERR_NORESPONSE;
448 state->state = TFTP_STATE_FIN;
452 if(data->state.upload) {
454 setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
455 state->data->req.upload_fromhere =
456 (char *)state->spacket.data + 4;
457 if(data->state.infilesize != -1)
458 Curl_pgrsSetUploadSize(data, data->state.infilesize);
462 setpacketevent(&state->spacket, TFTP_EVENT_RRQ);
467 result = Curl_urldecode(&state->data->state.up.path[1], 0,
472 if(strlen(filename) > (state->blksize - strlen(mode) - 4)) {
478 msnprintf((char *)state->spacket.data + 2,
479 state->blksize,
487 if(data->state.upload && (data->state.infilesize != -1))
489 data->state.infilesize);
493 result = tftp_option_add(state, &sbytes,
494 (char *)state->spacket.data + sbytes,
497 result = tftp_option_add(state, &sbytes,
498 (char *)state->spacket.data + sbytes, buf);
501 msnprintf(buf, sizeof(buf), "%d", state->requested_blksize);
503 result = tftp_option_add(state, &sbytes,
504 (char *)state->spacket.data + sbytes,
507 result = tftp_option_add(state, &sbytes,
508 (char *)state->spacket.data + sbytes, buf);
511 msnprintf(buf, sizeof(buf), "%d", state->retry_time);
513 result = tftp_option_add(state, &sbytes,
514 (char *)state->spacket.data + sbytes,
517 result = tftp_option_add(state, &sbytes,
518 (char *)state->spacket.data + sbytes, buf);
529 senddata = sendto(state->sockfd, (void *)state->spacket.data,
541 if(data->state.upload) {
542 result = tftp_connect_for_tx(state, event);
545 result = tftp_connect_for_rx(state, event);
550 result = tftp_connect_for_tx(state, event);
554 result = tftp_connect_for_rx(state, event);
558 state->state = TFTP_STATE_FIN;
562 failf(state->data, "tftp_send_first: internal error");
577 * Event handler for the RX state
580 static CURLcode tftp_rx(struct tftp_state_data *state,
585 struct Curl_easy *data = state->data;
592 rblock = getrpacketblock(&state->rpacket);
593 if(NEXT_BLOCKNUM(state->block) == rblock) {
595 state->retries = 0;
597 else if(state->block == rblock) {
606 rblock, NEXT_BLOCKNUM(state->block));
611 state->block = (unsigned short)rblock;
612 setpacketevent(&state->spacket, TFTP_EVENT_ACK);
613 setpacketblock(&state->spacket, state->block);
614 sbytes = sendto(state->sockfd, (void *)state->spacket.data,
616 (struct sockaddr *)&state->remote_addr,
617 state->remote_addrlen);
624 if(state->rbytes < (ssize_t)state->blksize + 4) {
625 state->state = TFTP_STATE_FIN;
628 state->state = TFTP_STATE_RX;
630 time(&state->rx_time);
635 state->block = 0;
636 state->retries = 0;
637 setpacketevent(&state->spacket, TFTP_EVENT_ACK);
638 setpacketblock(&state->spacket, state->block);
639 sbytes = sendto(state->sockfd, (void *)state->spacket.data,
641 (struct sockaddr *)&state->remote_addr,
642 state->remote_addrlen);
649 state->state = TFTP_STATE_RX;
650 time(&state->rx_time);
655 state->retries++;
658 NEXT_BLOCKNUM(state->block), state->retries);
659 if(state->retries > state->retry_max) {
660 state->error = TFTP_ERR_TIMEOUT;
661 state->state = TFTP_STATE_FIN;
665 sbytes = sendto(state->sockfd, (void *)state->spacket.data,
667 (struct sockaddr *)&state->remote_addr,
668 state->remote_addrlen);
677 setpacketevent(&state->spacket, TFTP_EVENT_ERROR);
678 setpacketblock(&state->spacket, state->block);
679 (void)sendto(state->sockfd, (void *)state->spacket.data,
681 (struct sockaddr *)&state->remote_addr,
682 state->remote_addrlen);
685 state->state = TFTP_STATE_FIN;
700 * Event handler for the TX state
703 static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event)
705 struct Curl_easy *data = state->data;
718 int rblock = getrpacketblock(&state->rpacket);
720 if(rblock != state->block &&
726 !(state->block == 0 && rblock == 65535)) {
729 rblock, state->block);
730 state->retries++;
732 if(state->retries>state->retry_max) {
734 state->block);
739 sbytes = sendto(state->sockfd, (void *)state->spacket.data,
740 4 + state->sbytes, SEND_4TH_ARG,
741 (struct sockaddr *)&state->remote_addr,
742 state->remote_addrlen);
755 time(&state->rx_time);
756 state->block++;
759 state->block = 1; /* first data block is 1 when using OACK */
761 state->retries = 0;
762 setpacketevent(&state->spacket, TFTP_EVENT_DATA);
763 setpacketblock(&state->spacket, state->block);
764 if(state->block > 1 && state->sbytes < state->blksize) {
765 state->state = TFTP_STATE_FIN;
773 state->sbytes = 0;
774 state->data->req.upload_fromhere = (char *)state->spacket.data + 4;
776 result = Curl_fillreadbuffer(data, state->blksize - state->sbytes, &cb);
779 state->sbytes += (int)cb;
780 state->data->req.upload_fromhere += cb;
781 } while(state->sbytes < state->blksize && cb);
783 sbytes = sendto(state->sockfd, (void *) state->spacket.data,
784 4 + state->sbytes, SEND_4TH_ARG,
785 (struct sockaddr *)&state->remote_addr,
786 state->remote_addrlen);
793 k->writebytecount += state->sbytes;
799 state->retries++;
801 " Retries = %d", NEXT_BLOCKNUM(state->block), state->retries);
803 if(state->retries > state->retry_max) {
804 state->error = TFTP_ERR_TIMEOUT;
805 state->state = TFTP_STATE_FIN;
809 sbytes = sendto(state->sockfd, (void *)state->spacket.data,
810 4 + state->sbytes, SEND_4TH_ARG,
811 (struct sockaddr *)&state->remote_addr,
812 state->remote_addrlen);
824 state->state = TFTP_STATE_FIN;
825 setpacketevent(&state->spacket, TFTP_EVENT_ERROR);
826 setpacketblock(&state->spacket, state->block);
827 (void)sendto(state->sockfd, (void *)state->spacket.data, 4, SEND_4TH_ARG,
828 (struct sockaddr *)&state->remote_addr,
829 state->remote_addrlen);
832 state->state = TFTP_STATE_FIN;
899 * The tftp state machine event dispatcher
902 static CURLcode tftp_state_machine(struct tftp_state_data *state,
906 struct Curl_easy *data = state->data;
908 switch(state->state) {
911 result = tftp_send_first(state, event);
915 result = tftp_rx(state, event);
919 result = tftp_tx(state, event);
925 DEBUGF(infof(data, "STATE: %d", state->state));
926 failf(data, "%s", "Internal state machine error");
944 struct tftp_state_data *state = conn->proto.tftpc;
949 if(state) {
950 Curl_safefree(state->rpacket.data);
951 Curl_safefree(state->spacket.data);
952 free(state);
967 struct tftp_state_data *state;
974 state = conn->proto.tftpc = calloc(1, sizeof(struct tftp_state_data));
975 if(!state)
988 if(!state->rpacket.data) {
989 state->rpacket.data = calloc(1, need_blksize + 2 + 2);
991 if(!state->rpacket.data)
995 if(!state->spacket.data) {
996 state->spacket.data = calloc(1, need_blksize + 2 + 2);
998 if(!state->spacket.data)
1006 state->data = data;
1007 state->sockfd = conn->sock[FIRSTSOCKET];
1008 state->state = TFTP_STATE_START;
1009 state->error = TFTP_ERR_NONE;
1010 state->blksize = TFTP_BLKSIZE_DEFAULT; /* Unless updated by OACK response */
1011 state->requested_blksize = blksize;
1013 ((struct sockaddr *)&state->local_addr)->sa_family =
1016 tftp_set_timeouts(state);
1032 int rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
1062 struct tftp_state_data *state = conn->proto.tftpc;
1071 if(state)
1072 result = tftp_translate_code(state->error);
1105 struct tftp_state_data *state = conn->proto.tftpc;
1109 state->rbytes = (int)recvfrom(state->sockfd,
1110 (void *)state->rpacket.data,
1111 state->blksize + 4,
1115 if(state->remote_addrlen == 0) {
1116 memcpy(&state->remote_addr, &fromaddr, fromlen);
1117 state->remote_addrlen = fromlen;
1121 if(state->rbytes < 4) {
1124 state->event = TFTP_EVENT_TIMEOUT;
1128 unsigned short event = getrpacketevent(&state->rpacket);
1129 state->event = (tftp_event_t)event;
1131 switch(state->event) {
1134 if(state->rbytes > 4 &&
1135 (NEXT_BLOCKNUM(state->block) == getrpacketblock(&state->rpacket))) {
1137 (char *)state->rpacket.data + 4,
1138 state->rbytes-4);
1140 tftp_state_machine(state, TFTP_EVENT_ERROR);
1147 unsigned short error = getrpacketblock(&state->rpacket);
1148 char *str = (char *)state->rpacket.data + 4;
1149 size_t strn = state->rbytes - 4;
1150 state->error = (tftp_error_t)error;
1158 result = tftp_parse_option_ack(state,
1159 (const char *)state->rpacket.data + 2,
1160 state->rbytes-2);
1173 tftp_state_machine(state, TFTP_EVENT_ERROR);
1192 struct tftp_state_data *state = conn->proto.tftpc;
1198 timeout_ms = Curl_timeleft(state->data, NULL,
1199 (state->state == TFTP_STATE_START));
1201 state->error = TFTP_ERR_TIMEOUT;
1202 state->state = TFTP_STATE_FIN;
1206 if(current > state->rx_time + state->retry_time) {
1209 time(&state->rx_time); /* update even though we received nothing */
1227 struct tftp_state_data *state = conn->proto.tftpc;
1237 result = tftp_state_machine(state, event);
1240 *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE;
1247 int rc = SOCKET_READABLE(state->sockfd, 0);
1254 state->event = TFTP_EVENT_ERROR;
1260 result = tftp_state_machine(state, state->event);
1263 *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE;
1290 /* The multi code doesn't have this logic for the DOING state so we
1292 state. */
1305 * Entry point for transfer from tftp_do, starts state mach
1312 struct tftp_state_data *state = conn->proto.tftpc;
1316 result = tftp_state_machine(state, TFTP_EVENT_INIT);
1318 if((state->state == TFTP_STATE_FIN) || result)
1342 struct tftp_state_data *state;
1354 state = conn->proto.tftpc;
1355 if(!state)
1364 result = tftp_translate_code(state->error);
1378 type = strstr(data->state.up.path, ";mode=");
1391 data->state.prefer_ascii = TRUE;
1398 data->state.prefer_ascii = FALSE;