/*---------------------------------------------------------------------------*/
static
PT_THREAD(pingreq_pt(struct pt *pt, struct mqtt_connection *conn))
{
  PT_BEGIN(pt);

  DBG("MQTT - Sending PINGREQ\n");

  /* Write Fixed Header */
  PT_MQTT_WRITE_BYTE(conn, MQTT_FHDR_MSG_TYPE_PINGREQ);
  PT_MQTT_WRITE_BYTE(conn, 0);

  send_out_buffer(conn);

  /* Start timeout for reply. */
  conn->waiting_for_pingresp = 1;

  /* Wait for PINGRESP or timeout */
  reset_packet(&conn->in_packet);
  timer_set(&conn->t, RESPONSE_WAIT_TIMEOUT);

  PT_WAIT_UNTIL(pt, conn->in_packet.packet_received || timer_expired(&conn->t));

  reset_packet(&conn->in_packet);

  conn->waiting_for_pingresp = 0;

  PT_END(pt);
}
Beispiel #2
0
/*---------------------------------------------------------------------------*/
static
PT_THREAD(pingreq_pt(struct pt* pt, struct mqtt_connection* conn))
{
  PT_BEGIN(pt);

  DBG("MQTT - Sending PINGREQ\r\n");

  /* Write Fixed Header */
  PT_MQTT_WRITE_BYTE(conn, MQTT_FHDR_MSG_TYPE_PINGREQ);
  PT_MQTT_WRITE_BYTE(conn, 0);

  send_out_buffer(conn);

  PT_WAIT_UNTIL(pt, conn->out_buffer_sent);

  /* Start timeout for reply. */
  conn->waiting_for_pingresp = 1;

  /* Wait for PINGRESP
   *
   * Note that the timeout disconnect is handle in the timer callback. */
  reset_packet(&conn->in_packet);
  do {
   PT_WAIT_UNTIL(pt, conn->in_packet.packet_received);
  } while((conn->in_packet.fhdr & 0xF0) != MQTT_FHDR_MSG_TYPE_PINGRESP);
  reset_packet(&conn->in_packet);

  conn->waiting_for_pingresp = 0;

  PT_END(pt);
}
Beispiel #3
0
/*---------------------------------------------------------------------------*/
static
PT_THREAD(subscribe_pt(struct pt* pt, struct mqtt_connection* conn))
{
  PT_BEGIN(pt);

  DBG("MQTT - Sending subscribe message! topic %s topic_length %i\r\n",
      conn->out_packet.topic,
      conn->out_packet.topic_length);
  DBG("MQTT - Buffer space is %i \r\n",
      &conn->out_buffer[MQTT_TCP_OUTPUT_BUFF_SIZE] - conn->out_buffer_ptr);

  /* Set up FHDR */
  conn->out_packet.fhdr = MQTT_FHDR_MSG_TYPE_SUBSCRIBE | MQTT_FHDR_QOS_LEVEL_1;
  conn->out_packet.remaining_length = MQTT_MID_SIZE +
                                      MQTT_STRING_LEN_SIZE +
                                      conn->out_packet.topic_length +
                                      MQTT_QOS_SIZE;
  encode_remaining_length(conn->out_packet.remaining_length_enc,
                          &conn->out_packet.remaining_length_enc_bytes,
                          conn->out_packet.remaining_length);
  if(conn->out_packet.remaining_length_enc_bytes > 4) {
    call_event(conn, MQTT_EVENT_PROTOCOL_ERROR, NULL);
    printf("MQTT - Error, remaining length > 4 bytes\r\n");
    PT_EXIT(pt);
  }

  /* Write Fixed Header */
  PT_MQTT_WRITE_BYTE(conn, conn->out_packet.fhdr);
  PT_MQTT_WRITE_BYTES(conn,
                      conn->out_packet.remaining_length_enc,
                      conn->out_packet.remaining_length_enc_bytes);
  /* Write Variable Header */
  PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid << 8));
  PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid & 0x00FF));
  /* Write Payload */
  PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length >> 8));
  PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length & 0x00FF));
  PT_MQTT_WRITE_BYTES(conn,
                      conn->out_packet.topic,
                      conn->out_packet.topic_length);
  PT_MQTT_WRITE_BYTE(conn, conn->out_packet.qos);

  /* Send out buffer */
  send_out_buffer(conn);

  /* Wait for SUBACK. */
  reset_packet(&conn->in_packet);
  do {
    PT_WAIT_UNTIL(pt, conn->out_packet.qos_state == MQTT_QOS_STATE_GOT_ACK);
  } while(conn->out_packet.qos_state != MQTT_QOS_STATE_GOT_ACK);
  reset_packet(&conn->in_packet);

  /* This is clear after the entire transaction is complete */
  conn->out_queue_full = 0;

  DBG("MQTT - Done in send_subscribe!\r\n");

  PT_END(pt);
}
/*---------------------------------------------------------------------------*/
static void
handle_publish(struct mqtt_connection *conn)
{
  DBG("MQTT - Got PUBLISH, called once per manageable chunk of message.\n");
  DBG("MQTT - Handling publish on topic '%s'\n", conn->in_publish_msg.topic);

  DBG("MQTT - This chunk is %i bytes\n", conn->in_packet.payload_pos);

  if(((conn->in_packet.fhdr & 0x09) >> 1) > 0) {
    PRINTF("MQTT - Error, got incoming PUBLISH with QoS > 0, not supported atm!\n");
  }

  call_event(conn, MQTT_EVENT_PUBLISH, &conn->in_publish_msg);

  if(conn->in_publish_msg.first_chunk == 1) {
    conn->in_publish_msg.first_chunk = 0;
  }

  /* If this is the last time handle_publish will be called, reset packet. */
  if(conn->in_publish_msg.payload_left == 0) {

    /* Check for QoS and initiate the reply, do not rely on the data in the
     * in_packet being untouched. */

    DBG("MQTT - (handle_publish) resetting packet.\n");
    reset_packet(&conn->in_packet);
  }
}
Beispiel #5
0
static int hls_read_seek(AVFormatContext *s, int stream_index,
                               int64_t timestamp, int flags)
{
    HLSContext *c = s->priv_data;
    int i, j, ret;

    if ((flags & AVSEEK_FLAG_BYTE) || !c->variants[0]->finished)
        return AVERROR(ENOSYS);

    c->seek_flags     = flags;
    c->seek_timestamp = stream_index < 0 ? timestamp :
                        av_rescale_rnd(timestamp, AV_TIME_BASE,
                                       s->streams[stream_index]->time_base.den,
                                       flags & AVSEEK_FLAG_BACKWARD ?
                                       AV_ROUND_DOWN : AV_ROUND_UP);
    timestamp = av_rescale_rnd(timestamp, 1, stream_index >= 0 ?
                               s->streams[stream_index]->time_base.den :
                               AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
                               AV_ROUND_DOWN : AV_ROUND_UP);
    if (s->duration < c->seek_timestamp) {
        c->seek_timestamp = AV_NOPTS_VALUE;
        return AVERROR(EIO);
    }

    ret = AVERROR(EIO);
    for (i = 0; i < c->n_variants; i++) {
        /* Reset reading */
        struct variant *var = c->variants[i];
        int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ? 0 :
                      av_rescale_rnd(c->first_timestamp, 1, stream_index >= 0 ?
                               s->streams[stream_index]->time_base.den :
                               AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
                               AV_ROUND_DOWN : AV_ROUND_UP);
         if (var->input) {
            ffurl_close(var->input);
            var->input = NULL;
        }
        av_free_packet(&var->pkt);
        reset_packet(&var->pkt);
        var->pb.eof_reached = 0;
        /* Clear any buffered data */
        var->pb.buf_end = var->pb.buf_ptr = var->pb.buffer;
        /* Reset the pos, to let the mpegts demuxer know we've seeked. */
        var->pb.pos = 0;

        /* Locate the segment that contains the target timestamp */
        for (j = 0; j < var->n_segments; j++) {
            if (timestamp >= pos &&
                timestamp < pos + var->segments[j]->duration) {
                var->cur_seq_no = var->start_seq_no + j;
                ret = 0;
                break;
            }
            pos += var->segments[j]->duration;
        }
        if (ret)
            c->seek_timestamp = AV_NOPTS_VALUE;
    }
    return ret;
}
Beispiel #6
0
static int applehttp_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    AppleHTTPContext *c = s->priv_data;
    int ret, i, minvariant = -1;

    if (c->first_packet) {
        recheck_discard_flags(s, 1);
        c->first_packet = 0;
    }

start:
    c->end_of_segment = 0;
    for (i = 0; i < c->n_variants; i++) {
        struct variant *var = c->variants[i];
        /* Make sure we've got one buffered packet from each open variant
         * stream */
        if (var->needed && !var->pkt.data) {
            ret = av_read_frame(var->ctx, &var->pkt);
            if (ret < 0) {
                if (!var->pb.eof_reached)
                    return ret;
                reset_packet(&var->pkt);
            } else {
                if (c->first_timestamp == AV_NOPTS_VALUE)
                    c->first_timestamp = var->pkt.dts;
            }
        }
        /* Check if this stream has the packet with the lowest dts */
        if (var->pkt.data) {
            if (minvariant < 0 ||
                var->pkt.dts < c->variants[minvariant]->pkt.dts)
                minvariant = i;
        }
    }
    if (c->end_of_segment) {
        if (recheck_discard_flags(s, 0))
            goto start;
    }
    /* If we got a packet, return it */
    if (minvariant >= 0) {
        *pkt = c->variants[minvariant]->pkt;
        pkt->stream_index += c->variants[minvariant]->stream_offset;
        reset_packet(&c->variants[minvariant]->pkt);
        return 0;
    }
    return AVERROR_EOF;
}
/*---------------------------------------------------------------------------*/
static void
reset_defaults(struct mqtt_connection *conn)
{
  conn->mid_counter = 1;
  PT_INIT(&conn->out_proto_thread);
  conn->waiting_for_pingresp = 0;

  reset_packet(&conn->in_packet);
  conn->out_buffer_sent = 0;
}
Beispiel #8
0
static struct playlist *new_playlist(HLSContext *c, const char *url,
                                     const char *base)
{
    struct playlist *pls = av_mallocz(sizeof(struct playlist));
    if (!pls)
        return NULL;
    reset_packet(&pls->pkt);
    ff_make_absolute_url(pls->url, sizeof(pls->url), base, url);
    dynarray_add(&c->playlists, &c->n_playlists, pls);
    return pls;
}
Beispiel #9
0
static struct variant *new_variant(HLSContext *c, int bandwidth,
                                   const char *url, const char *base)
{
    struct variant *var = av_mallocz(sizeof(struct variant));
    if (!var)
        return NULL;
    reset_packet(&var->pkt);
    var->bandwidth = bandwidth;
    ff_make_absolute_url(var->url, sizeof(var->url), base, url);
    dynarray_add(&c->variants, &c->n_variants, var);
    return var;
}
Beispiel #10
0
static int applehttp_read_seek(AVFormatContext *s, int stream_index,
                               int64_t timestamp, int flags)
{
    AppleHTTPContext *c = s->priv_data;
    int i, j, ret;

    if ((flags & AVSEEK_FLAG_BYTE) || !c->variants[0]->finished)
        return AVERROR(ENOSYS);

    timestamp = av_rescale_rnd(timestamp, 1, stream_index >= 0 ?
                               s->streams[stream_index]->time_base.den :
                               AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
                               AV_ROUND_DOWN : AV_ROUND_UP);
    ret = AVERROR(EIO);
    for (i = 0; i < c->n_variants; i++) {
        /* Reset reading */
        struct variant *var = c->variants[i];
        int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ? 0 :
                      av_rescale_rnd(c->first_timestamp, 1,
                          stream_index >= 0 ? s->streams[stream_index]->time_base.den : AV_TIME_BASE,
                          flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP);
        if (var->input) {
            ffurl_close(var->input);
            var->input = NULL;
        }
        av_free_packet(&var->pkt);
        reset_packet(&var->pkt);
        var->pb.eof_reached = 0;

        /* Locate the segment that contains the target timestamp */
        for (j = 0; j < var->n_segments; j++) {
            if (timestamp >= pos &&
                timestamp < pos + var->segments[j]->duration) {
                var->cur_seq_no = var->start_seq_no + j;
                ret = 0;
                break;
            }
            pos += var->segments[j]->duration;
        }
    }
    return ret;
}
Beispiel #11
0
static int open_variant(AppleHTTPContext *c, struct variant *var, int skip)
{
    int ret;

    if (c->cur_seq_no < var->start_seq_no) {
        av_log(NULL, AV_LOG_WARNING,
               "seq %d not available in variant %s, skipping\n",
               var->start_seq_no, var->url);
        return 0;
    }
    if (c->cur_seq_no - var->start_seq_no >= var->n_segments)
        return c->finished ? AVERROR_EOF : 0;
    ret = url_fopen(&var->pb,
                    var->segments[c->cur_seq_no - var->start_seq_no]->url,
                    URL_RDONLY);
    if (ret < 0)
        return ret;
    var->ctx->pb = var->pb;
    /* If this is a new segment in parallel with another one already opened,
     * skip ahead so they're all at the same dts. */
    if (skip && c->last_packet_dts != AV_NOPTS_VALUE) {
        while (1) {
            ret = av_read_frame(var->ctx, &var->pkt);
            if (ret < 0) {
                if (ret == AVERROR_EOF) {
                    reset_packet(&var->pkt);
                    return 0;
                }
                return ret;
            }
            if (var->pkt.dts >= c->last_packet_dts)
                break;
            av_free_packet(&var->pkt);
        }
    }
    return 0;
}
Beispiel #12
0
int alloc_free_queue(nic_t *nic, size_t num_of_packets)
{
	int i;

	pthread_mutex_lock(&nic->free_packet_queue_mutex);
	for (i = 0; i < num_of_packets; i++) {
		packet_t *pkt;

		pkt = alloc_packet(STD_MTU_SIZE, STD_MTU_SIZE);
		if (pkt == NULL) {
			goto done;
		}

		reset_packet(pkt);

		pkt->next = nic->free_packet_queue;
		nic->free_packet_queue = pkt;
	}

done:
	pthread_mutex_unlock(&nic->free_packet_queue_mutex);

	return i;
}
Beispiel #13
0
static int applehttp_read_seek(AVFormatContext *s, int stream_index,
                               int64_t timestamp, int flags)
{
    AppleHTTPContext *c = s->priv_data;
    int pos = 0, i;
    struct variant *var = c->variants[0];

    if ((flags & AVSEEK_FLAG_BYTE) || !c->finished)
        return AVERROR(ENOSYS);

    /* Reset the variants */
    c->last_packet_dts = AV_NOPTS_VALUE;
    for (i = 0; i < c->n_variants; i++) {
        struct variant *var = c->variants[i];
        if (var->pb) {
            url_fclose(var->pb);
            var->pb = NULL;
        }
        av_free_packet(&var->pkt);
        reset_packet(&var->pkt);
    }

    timestamp = av_rescale_rnd(timestamp, 1, stream_index >= 0 ?
                               s->streams[stream_index]->time_base.den :
                               AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
                               AV_ROUND_DOWN : AV_ROUND_UP);
    /* Locate the segment that contains the target timestamp */
    for (i = 0; i < var->n_segments; i++) {
        if (timestamp >= pos && timestamp < pos + var->segments[i]->duration) {
            c->cur_seq_no = var->start_seq_no + i;
            return 0;
        }
        pos += var->segments[i]->duration;
    }
    return AVERROR(EIO);
}
Beispiel #14
0
/*---------------------------------------------------------------------------*/
static
PT_THREAD(connect_pt(struct pt* pt, struct mqtt_connection* conn))
{
  PT_BEGIN(pt);

  DBG("MQTT - Sending CONNECT message...\r\n");

  /* Set up FHDR */
  conn->out_packet.fhdr = MQTT_FHDR_MSG_TYPE_CONNECT;
  conn->out_packet.remaining_length = 0;
  conn->out_packet.remaining_length += MQTT_connect_vhdr_flags_SIZE;
  conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->client_id);
  conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->credentials.username);
  conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->credentials.password);
  conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->will.topic);
  conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->will.message);
  encode_remaining_length(conn->out_packet.remaining_length_enc,
                          &conn->out_packet.remaining_length_enc_bytes,
                          conn->out_packet.remaining_length);
  if(conn->out_packet.remaining_length_enc_bytes > 4) {
    call_event(conn, MQTT_EVENT_PROTOCOL_ERROR, NULL);
    printf("MQTT - Error, remaining length > 4 bytes\r\n");
    PT_EXIT(pt);
  }

  /* Write Fixed Header */
  PT_MQTT_WRITE_BYTE(conn, conn->out_packet.fhdr);
  PT_MQTT_WRITE_BYTES(conn,
                      conn->out_packet.remaining_length_enc,
                      conn->out_packet.remaining_length_enc_bytes);
  PT_MQTT_WRITE_BYTE(conn, 0);
  PT_MQTT_WRITE_BYTE(conn, 6);
  PT_MQTT_WRITE_BYTES(conn, (uint8_t*)MQTT_PROTOCOL_NAME, 6);
  PT_MQTT_WRITE_BYTE(conn, MQTT_PROTOCOL_VERSION);
  PT_MQTT_WRITE_BYTE(conn, conn->connect_vhdr_flags);
  PT_MQTT_WRITE_BYTE(conn, (conn->keep_alive >> 8));
  PT_MQTT_WRITE_BYTE(conn, (conn->keep_alive & 0x00FF));
  PT_MQTT_WRITE_BYTE(conn, conn->client_id.length << 8);
  PT_MQTT_WRITE_BYTE(conn, conn->client_id.length & 0x00FF);
  PT_MQTT_WRITE_BYTES(conn, conn->client_id.string, conn->client_id.length);
  if(conn->connect_vhdr_flags & MQTT_VHDR_WILL_FLAG) {
    PT_MQTT_WRITE_BYTE(conn, conn->will.topic.length << 8);
    PT_MQTT_WRITE_BYTE(conn, conn->will.topic.length & 0x00FF);
    PT_MQTT_WRITE_BYTES(conn, conn->will.topic.string, conn->will.topic.length);
    PT_MQTT_WRITE_BYTE(conn, conn->will.message.length << 8);
    PT_MQTT_WRITE_BYTE(conn, conn->will.message.length & 0x00FF);
    PT_MQTT_WRITE_BYTES(conn, conn->will.message.string, conn->will.message.length);
    DBG("MQTT - Setting will topic to '%s' %i bytes and message to '%s' %i bytes\r\n",
        conn->will.topic.string,
        conn->will.topic.length,
        conn->will.message.string,
        conn->will.message.length);
  }
  if(conn->connect_vhdr_flags & MQTT_VHDR_USERNAME_FLAG) {
    DBG("MQTT - Setting username\r\n");
    PT_MQTT_WRITE_BYTE(conn, conn->credentials.username.length << 8);
    PT_MQTT_WRITE_BYTE(conn, conn->credentials.username.length & 0x00FF);
    PT_MQTT_WRITE_BYTES(conn,
                        conn->credentials.username.string,
                        conn->credentials.username.length);
  }
  if(conn->connect_vhdr_flags & MQTT_VHDR_PASSWORD_FLAG) {
    DBG("MQTT - Setting password\r\n");    
    PT_MQTT_WRITE_BYTE(conn, conn->credentials.password.length << 8);
    PT_MQTT_WRITE_BYTE(conn, conn->credentials.password.length & 0x00FF);
    PT_MQTT_WRITE_BYTES(conn,
                        conn->credentials.password.string,
                        conn->credentials.password.length);
  }

  /* Send out buffer */
  send_out_buffer(conn);
  conn->state = MQTT_CONN_STATE_CONNECTING_TO_BROKER;

  /* Wait for CONNACK */
  reset_packet(&conn->in_packet);
  do {
    PT_WAIT_UNTIL(pt, conn->out_packet.qos_state == MQTT_QOS_STATE_GOT_ACK);
  } while(conn->out_packet.qos_state != MQTT_QOS_STATE_GOT_ACK);
  reset_packet(&conn->in_packet);

  DBG("MQTT - Done sending CONNECT since we got CONNACK!\r\n");

#if DEBUG_MQTT == 1
  DBG("MQTT - Sending CONNECT message: \r\n");
  uint16_t i;
  for( i = 0; i < (conn->out_buffer_ptr - conn->out_buffer); i++ ) {
    DBG( "%02X ", conn->out_buffer[i] );
  }
  DBG("\r\n");
#endif

  PT_END(pt);
}
Beispiel #15
0
static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    HLSContext *c = s->priv_data;
    int ret, i, minvariant = -1;

    if (c->first_packet) {
        recheck_discard_flags(s, 1);
        c->first_packet = 0;
    }

start:
    c->end_of_segment = 0;
    for (i = 0; i < c->n_variants; i++) {
        struct variant *var = c->variants[i];
        /* Make sure we've got one buffered packet from each open variant
         * stream */
        if (var->needed && !var->pkt.data) {
            while (1) {
                int64_t ts_diff;
                AVStream *st;
                ret = av_read_frame(var->ctx, &var->pkt);
                if (ret < 0) {
                    if (!url_feof(&var->pb) && ret != AVERROR_EOF)
                        return ret;
                    reset_packet(&var->pkt);
                    break;
                } else {
                    if (c->first_timestamp == AV_NOPTS_VALUE)
                        c->first_timestamp = var->pkt.dts;
                }

                if (c->seek_timestamp == AV_NOPTS_VALUE)
                    break;

                if (var->pkt.dts == AV_NOPTS_VALUE) {
                    c->seek_timestamp = AV_NOPTS_VALUE;
                    break;
                }

                st = var->ctx->streams[var->pkt.stream_index];
                ts_diff = av_rescale_rnd(var->pkt.dts, AV_TIME_BASE,
                                         st->time_base.den, AV_ROUND_DOWN) -
                          c->seek_timestamp;
                if (ts_diff >= 0 && (c->seek_flags  & AVSEEK_FLAG_ANY ||
                                     var->pkt.flags & AV_PKT_FLAG_KEY)) {
                    c->seek_timestamp = AV_NOPTS_VALUE;
                    break;
                }
            }
        }
        /* Check if this stream has the packet with the lowest dts */
        if (var->pkt.data) {
            if(minvariant < 0) {
                minvariant = i;
            } else {
                struct variant *minvar = c->variants[minvariant];
                int64_t dts    =    var->pkt.dts;
                int64_t mindts = minvar->pkt.dts;
                AVStream *st   =    var->ctx->streams[   var->pkt.stream_index];
                AVStream *minst= minvar->ctx->streams[minvar->pkt.stream_index];

                if(   st->start_time != AV_NOPTS_VALUE)    dts -=    st->start_time;
                if(minst->start_time != AV_NOPTS_VALUE) mindts -= minst->start_time;

                if (av_compare_ts(dts, st->time_base, mindts, minst->time_base) < 0)
                    minvariant = i;
            }
        }
    }
    if (c->end_of_segment) {
        if (recheck_discard_flags(s, 0))
            goto start;
    }
    /* If we got a packet, return it */
    if (minvariant >= 0) {
        *pkt = c->variants[minvariant]->pkt;
        pkt->stream_index += c->variants[minvariant]->stream_offset;
        reset_packet(&c->variants[minvariant]->pkt);
        return 0;
    }
    return AVERROR_EOF;
}
Beispiel #16
0
static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    HLSContext *c = s->priv_data;
    int ret, i, minvariant = -1;

    if (c->first_packet) {
        recheck_discard_flags(s, 1);
        c->first_packet = 0;
    }
//    __android_log_print(ANDROID_LOG_VERBOSE, TAG, "hls_read_packet,n_variants = %d", c->n_variants);
start:
    c->end_of_segment = 0;
    for (i = 0; i < c->n_variants; i++) {
        struct variant *var = c->variants[i];
        /* Make sure we've got one buffered packet from each open variant
         * stream */
        if (var->needed && !var->pkt.data) {
            while (1) {
                int64_t ts_diff;
                AVStream *st;
                ret = av_read_frame(var->ctx, &var->pkt);
                if (ret < 0) {
                    if (!url_feof(&var->pb))
                        return ret;
                    reset_packet(&var->pkt);
                    break;
                }
#if 0 // Modify By Yen For Test
				else {
                    if (c->first_timestamp == AV_NOPTS_VALUE) 
                        c->first_timestamp = var->pkt.dts;
                }
#endif						
                if (c->seek_timestamp == AV_NOPTS_VALUE) {
                    break;
                }
                if (var->pkt.dts == AV_NOPTS_VALUE) {
                    c->seek_timestamp = AV_NOPTS_VALUE;
                    break;
                }
                st = var->ctx->streams[var->pkt.stream_index];
                ts_diff = av_rescale_rnd(var->pkt.dts, AV_TIME_BASE,
                                         st->time_base.den, AV_ROUND_DOWN) -
                          c->seek_timestamp;
                if (ts_diff >= 0 && (c->seek_flags  & AVSEEK_FLAG_ANY ||
                                     var->pkt.flags & AV_PKT_FLAG_KEY)) {
                    c->seek_timestamp = AV_NOPTS_VALUE;
                    break;
                }
            }
        }
        /* Check if this stream has the packet with the lowest dts */
        if (var->pkt.data) {
            if (minvariant < 0 ||
                var->pkt.dts < c->variants[minvariant]->pkt.dts)
                minvariant = i;
        }
    }
    if (c->end_of_segment) {
        if (recheck_discard_flags(s, 0))
            goto start;
    }
    /* If we got a packet, return it */
    if (minvariant >= 0) {
        *pkt = c->variants[minvariant]->pkt;
        pkt->stream_index += c->variants[minvariant]->stream_offset;
        reset_packet(&c->variants[minvariant]->pkt);
        return 0;
    }
    return AVERROR_EOF;
}
/*---------------------------------------------------------------------------*/
static int
tcp_input(struct tcp_socket *s,
          void *ptr,
          const uint8_t *input_data_ptr,
          int input_data_len)
{
  struct mqtt_connection *conn = ptr;
  uint32_t pos = 0;
  uint32_t copy_bytes = 0;
  uint8_t byte;

  if(input_data_len == 0) {
    return 0;
  }

  if(conn->in_packet.packet_received) {
    reset_packet(&conn->in_packet);
  }

  DBG("tcp_input with %i bytes of data:\n", input_data_len);

  /* Read the fixed header field, if we do not have it */
  if(!conn->in_packet.fhdr) {
    conn->in_packet.fhdr = input_data_ptr[pos++];
    conn->in_packet.byte_counter++;

    DBG("MQTT - Read VHDR '%02X'\n", conn->in_packet.fhdr);

    if(pos >= input_data_len) {
      return 0;
    }
  }

  /* Read the Remaining Length field, if we do not have it */
  if(!conn->in_packet.has_remaining_length) {
    do {
      if(pos >= input_data_len) {
        return 0;
      }

      byte = input_data_ptr[pos++];
      conn->in_packet.byte_counter++;
      conn->in_packet.remaining_length_bytes++;
      DBG("MQTT - Read Remaining Length byte\n");

      if(conn->in_packet.byte_counter > 5) {
        call_event(conn, MQTT_EVENT_ERROR, NULL);
        DBG("Received more then 4 byte 'remaining lenght'.");
        return 0;
      }

      conn->in_packet.remaining_length +=
        (byte & 127) * conn->in_packet.remaining_multiplier;
      conn->in_packet.remaining_multiplier *= 128;
    } while((byte & 128) != 0);

    DBG("MQTT - Finished reading remaining length byte\n");
    conn->in_packet.has_remaining_length = 1;
  }

  /*
   * Check for unsupported payload length. Will read all incoming data from the
   * server in any case and then reset the packet.
   *
   * TODO: Decide if we, for example, want to disconnect instead.
   */
  if((conn->in_packet.remaining_length > MQTT_INPUT_BUFF_SIZE) &&
     (conn->in_packet.fhdr & 0xF0) != MQTT_FHDR_MSG_TYPE_PUBLISH) {

    PRINTF("MQTT - Error, unsupported payload size for non-PUBLISH message\n");

    conn->in_packet.byte_counter += input_data_len;
    if(conn->in_packet.byte_counter >=
       (MQTT_FHDR_SIZE + conn->in_packet.remaining_length)) {
      conn->in_packet.packet_received = 1;
    }
    return 0;
  }

  /*
   * Supported payload, reads out both VHDR and Payload of all packets.
   *
   * Note: There will always be at least one byte left to read when we enter
   *       this loop.
   */
  while(conn->in_packet.byte_counter <
        (MQTT_FHDR_SIZE + conn->in_packet.remaining_length)) {

    if((conn->in_packet.fhdr & 0xF0) == MQTT_FHDR_MSG_TYPE_PUBLISH &&
       conn->in_packet.topic_received == 0) {
      parse_publish_vhdr(conn, &pos, input_data_ptr, input_data_len);
    }

    /* Read in as much as we can into the packet payload */
    copy_bytes = MIN(input_data_len - pos,
                     MQTT_INPUT_BUFF_SIZE - conn->in_packet.payload_pos);
    DBG("- Copied %lu payload bytes\n", copy_bytes);
    memcpy(&conn->in_packet.payload[conn->in_packet.payload_pos],
           &input_data_ptr[pos],
           copy_bytes);
    conn->in_packet.byte_counter += copy_bytes;
    conn->in_packet.payload_pos += copy_bytes;
    pos += copy_bytes;

    uint8_t i;
    DBG("MQTT - Copied bytes: \n");
    for(i = 0; i < copy_bytes; i++) {
      DBG("%02X ", conn->in_packet.payload[i]);
    }
    DBG("\n");

    /* Full buffer, shall only happen to PUBLISH messages. */
    if(MQTT_INPUT_BUFF_SIZE - conn->in_packet.payload_pos == 0) {
      conn->in_publish_msg.payload_chunk = conn->in_packet.payload;
      conn->in_publish_msg.payload_chunk_length = MQTT_INPUT_BUFF_SIZE;
      conn->in_publish_msg.payload_left -= MQTT_INPUT_BUFF_SIZE;

      handle_publish(conn);

      conn->in_publish_msg.payload_chunk = conn->in_packet.payload;
      conn->in_packet.payload_pos = 0;
    }

    if(pos >= input_data_len &&
       (conn->in_packet.byte_counter < (MQTT_FHDR_SIZE + conn->in_packet.remaining_length))) {
      return 0;
    }
  }

  /* Debug information */
  DBG("\n");
  /* Take care of input */
  DBG("MQTT - Finished reading packet!\n");
  /* What to return? */
  DBG("MQTT - total data was %i bytes of data. \n",
      (MQTT_FHDR_SIZE + conn->in_packet.remaining_length));

  /* Handle packet here. */
  switch(conn->in_packet.fhdr & 0xF0) {
  case MQTT_FHDR_MSG_TYPE_CONNACK:
    handle_connack(conn);
    break;
  case MQTT_FHDR_MSG_TYPE_PUBLISH:
    /* This is the only or the last chunk of publish payload */
    conn->in_publish_msg.payload_chunk = conn->in_packet.payload;
    conn->in_publish_msg.payload_chunk_length = conn->in_packet.payload_pos;
    conn->in_publish_msg.payload_left = 0;
    handle_publish(conn);
    break;
  case MQTT_FHDR_MSG_TYPE_PUBACK:
    handle_puback(conn);
    break;
  case MQTT_FHDR_MSG_TYPE_SUBACK:
    handle_suback(conn);
    break;
  case MQTT_FHDR_MSG_TYPE_UNSUBACK:
    handle_unsuback(conn);
    break;
  case MQTT_FHDR_MSG_TYPE_PINGRESP:
    handle_pingresp(conn);
    break;

  /* QoS 2 not implemented yet */
  case MQTT_FHDR_MSG_TYPE_PUBREC:
  case MQTT_FHDR_MSG_TYPE_PUBREL:
  case MQTT_FHDR_MSG_TYPE_PUBCOMP:
    call_event(conn, MQTT_EVENT_NOT_IMPLEMENTED_ERROR, NULL);
    PRINTF("MQTT - Got unhandled MQTT Message Type '%i'",
           (conn->in_packet.fhdr & 0xF0));
    break;

  default:
    /* All server-only message */
    PRINTF("MQTT - Got MQTT Message Type '%i'", (conn->in_packet.fhdr & 0xF0));
    break;
  }

  conn->in_packet.packet_received = 1;

  return 0;
}
Beispiel #18
0
static int hls_read_seek(AVFormatContext *s, int stream_index,
                               int64_t timestamp, int flags)
{
    HLSContext *c = s->priv_data;
    int i, j, ret;
    //__android_log_print(ANDROID_LOG_INFO, TAG,"func:%s line:%d timestamp = %f", __func__, __LINE__,
    //		(double)(timestamp/1000000.0));
    if ((flags & AVSEEK_FLAG_BYTE) 
#if 0 // modified by yen for TSTV	
	|| !c->variants[0]->finished
#endif	
	) {
        return AVERROR(ENOSYS);
    }
    c->seek_flags     = flags;
    c->seek_timestamp = stream_index < 0 ? timestamp :
                        av_rescale_rnd(timestamp, AV_TIME_BASE,
                                       s->streams[stream_index]->time_base.den,
                                       flags & AVSEEK_FLAG_BACKWARD ?
                                       AV_ROUND_DOWN : AV_ROUND_UP);
    timestamp = av_rescale_rnd(timestamp, 1, stream_index >= 0 ?
                               s->streams[stream_index]->time_base.den :
                               AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
                               AV_ROUND_DOWN : AV_ROUND_UP);
#if 0 // modified by yen for TSTV
    if (s->duration < c->seek_timestamp) {
        c->seek_timestamp = AV_NOPTS_VALUE;
        //__android_log_print(ANDROID_LOG_VERBOSE, TAG, "hls_read_seek,return err 2");
        return AVERROR(EIO);
    }
#endif
    ret = AVERROR(EIO);
    for (i = 0; i < c->n_variants; i++) {
        /* Reset reading */
        struct variant *var = c->variants[i];
        int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ? 0 :
                      av_rescale_rnd(c->first_timestamp, 
					           1, // modified by yen from 1->AV_TIME_BASE (second->microsecond)
                               stream_index >= 0 ?
                               s->streams[stream_index]->time_base.den :
                               AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
                               AV_ROUND_DOWN : AV_ROUND_UP);
         if (var->input) {
            ffurl_close(var->input);
            var->input = NULL;
        }
        av_free_packet(&var->pkt);
        reset_packet(&var->pkt);
        var->pb.eof_reached = 0;
        /* Clear any buffered data */
        var->pb.buf_end = var->pb.buf_ptr = var->pb.buffer;
        /* Reset the pos, to let the mpegts demuxer know we've seeked. */
        var->pb.pos = 0;


        //__android_log_print(ANDROID_LOG_WARN, TAG, "hls_read_seek POS,first_timestamp:%f,seek_timestamp:%f,pos:%f",
    	//	(double)(c->first_timestamp/1000000.0),(double)(c->seek_timestamp/AV_TIME_BASE),(double)(pos/1000000.0));


        /**
         * Yen: if seek_timestamp lower then position that we set position = start_seq_no
         *      if seek_timestamp biger then duration that we set position = last_seq_no - 3
         */

//        if(c->seek_timestamp == 0) {
//        	var->cur_seq_no = var->start_seq_no;
//        	ret = 0;
////            __android_log_print(ANDROID_LOG_VERBOSE, TAG, "hls_read_seek 0,ok,seek_timestamp:%f,pos:%f,max:%f",
////        		(double)c->seek_timestamp/1000000.0,(double)pos/1000000.0,(double)((pos + (var->segments[j]->duration*AV_TIME_BASE))/AV_TIME_BASE));
//
//        	break;
//        }
//
//        if(c->seek_timestamp <= pos) {
//        	var->cur_seq_no = var->start_seq_no;
//        	ret = 0;
////            __android_log_print(ANDROID_LOG_VERBOSE, TAG, "hls_read_seek 1,ok,seek_timestamp:%f,pos:%f,max:%f",
////        		(double)c->seek_timestamp/1000000.0,(double)pos/1000000.0,(double)((pos + (var->segments[j]->duration*AV_TIME_BASE))/AV_TIME_BASE));
//
//        	break;
//        }
//        else if(c->seek_timestamp >= (pos + s->duration)) {
//        	var->cur_seq_no = var->start_seq_no + var->n_segments - 3;
//        	ret = 0;
////            __android_log_print(ANDROID_LOG_VERBOSE, TAG, "hls_read_seek 2,ok,seek_timestamp:%f,pos:%f,max:%f,cur_seq_no:%d,n_segments:%d",
////        		(double)c->seek_timestamp/1000000.0,(double)pos/1000000.0,(double)((pos + (s->duration))/AV_TIME_BASE),var->cur_seq_no,var->n_segments);
//
//        	break;
//        }


        /* Locate the segment that contains the target timestamp */
        for (j = 0; j < var->n_segments; j++) {
            if (c->seek_timestamp > pos & c->seek_timestamp < (pos + (var->segments[j]->duration*AV_TIME_BASE))) { // modified by yen second->microsecond (*AV_TIME_BASE)
                var->cur_seq_no = var->start_seq_no + j;
                ret = 0;
//                __android_log_print(ANDROID_LOG_VERBOSE, TAG, "hls_read_seek 3,ok,seek_timestamp:%f,pos:%f,max:%f,cur_seq_no:%d,n_segments:%d",
//            		(double)c->seek_timestamp/1000000.0,(double)pos/1000000.0,(double)((pos + (var->segments[j]->duration*AV_TIME_BASE))/AV_TIME_BASE),var->cur_seq_no,var->n_segments);
                break;
            }
            pos += var->segments[j]->duration*AV_TIME_BASE;  // modified by yen same as up
//            __android_log_print(ANDROID_LOG_VERBOSE, TAG, "hls_read_seek,err,seek_timestamp:%f,pos:%f,max:%f,duration:%d",
//        		(double)c->seek_timestamp/1000000.0,(double)pos/1000000.0,(double)((pos + (var->segments[j]->duration*AV_TIME_BASE))/AV_TIME_BASE),var->segments[j]->duration);
        }
//        if (ret)
//            c->seek_timestamp = AV_NOPTS_VALUE;
    }
    return ret;
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(publish_pt(struct pt *pt, struct mqtt_connection *conn))
{
  PT_BEGIN(pt);

  DBG("MQTT - Sending publish message! topic %s topic_length %i\n",
      conn->out_packet.topic,
      conn->out_packet.topic_length);
  DBG("MQTT - Buffer space is %i \n",
      &conn->out_buffer[MQTT_TCP_OUTPUT_BUFF_SIZE] - conn->out_buffer_ptr);

  /* Set up FHDR */
  conn->out_packet.fhdr = MQTT_FHDR_MSG_TYPE_PUBLISH |
    conn->out_packet.qos << 1;
  if(conn->out_packet.retain == MQTT_RETAIN_ON) {
    conn->out_packet.fhdr |= MQTT_FHDR_RETAIN_FLAG;
  }
  conn->out_packet.remaining_length = MQTT_STRING_LEN_SIZE +
    conn->out_packet.topic_length +
    conn->out_packet.payload_size;
  if(conn->out_packet.qos > MQTT_QOS_LEVEL_0) {
    conn->out_packet.remaining_length += MQTT_MID_SIZE;
  }
  encode_remaining_length(conn->out_packet.remaining_length_enc,
                          &conn->out_packet.remaining_length_enc_bytes,
                          conn->out_packet.remaining_length);
  if(conn->out_packet.remaining_length_enc_bytes > 4) {
    call_event(conn, MQTT_EVENT_PROTOCOL_ERROR, NULL);
    PRINTF("MQTT - Error, remaining length > 4 bytes\n");
    PT_EXIT(pt);
  }

  /* Write Fixed Header */
  PT_MQTT_WRITE_BYTE(conn, conn->out_packet.fhdr);
  PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->out_packet.remaining_length_enc,
                      conn->out_packet.remaining_length_enc_bytes);
  /* Write Variable Header */
  PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length >> 8));
  PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length & 0x00FF));
  PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->out_packet.topic,
                      conn->out_packet.topic_length);
  if(conn->out_packet.qos > MQTT_QOS_LEVEL_0) {
    PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid << 8));
    PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid & 0x00FF));
  }
  /* Write Payload */
  PT_MQTT_WRITE_BYTES(conn,
                      conn->out_packet.payload,
                      conn->out_packet.payload_size);

  send_out_buffer(conn);
  timer_set(&conn->t, RESPONSE_WAIT_TIMEOUT);

  /*
   * If QoS is zero then wait until the message has been sent, since there is
   * no ACK to wait for.
   *
   * Also notify the app will not be notified via PUBACK or PUBCOMP
   */
  if(conn->out_packet.qos == 0) {
    process_post(conn->app_process, mqtt_update_event, NULL);
  } else if(conn->out_packet.qos == 1) {
    /* Wait for PUBACK */
    reset_packet(&conn->in_packet);
    PT_WAIT_UNTIL(pt, conn->out_packet.qos_state == MQTT_QOS_STATE_GOT_ACK ||
                  timer_expired(&conn->t));
    if(timer_expired(&conn->t)) {
      DBG("Timeout waiting for PUBACK\n");
    }
    if(conn->in_packet.mid != conn->out_packet.mid) {
      DBG("MQTT - Warning, got PUBACK with none matching MID. Currently there "
          "is no support for several concurrent PUBLISH messages.\n");
    }
  } else if(conn->out_packet.qos == 2) {
    DBG("MQTT - QoS not implemented yet.\n");
    /* Should wait for PUBREC, send PUBREL and then wait for PUBCOMP */
  }

  reset_packet(&conn->in_packet);

  /* This is clear after the entire transaction is complete */
  conn->out_queue_full = 0;

  DBG("MQTT - Publish Enqueued\n");

  PT_END(pt);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(unsubscribe_pt(struct pt *pt, struct mqtt_connection *conn))
{
  PT_BEGIN(pt);

  DBG("MQTT - Sending unsubscribe message on topic %s topic_length %i\n",
      conn->out_packet.topic,
      conn->out_packet.topic_length);
  DBG("MQTT - Buffer space is %i \n",
      &conn->out_buffer[MQTT_TCP_OUTPUT_BUFF_SIZE] - conn->out_buffer_ptr);

  /* Set up FHDR */
  conn->out_packet.fhdr = MQTT_FHDR_MSG_TYPE_UNSUBSCRIBE |
    MQTT_FHDR_QOS_LEVEL_1;
  conn->out_packet.remaining_length = MQTT_MID_SIZE +
    MQTT_STRING_LEN_SIZE +
    conn->out_packet.topic_length;
  encode_remaining_length(conn->out_packet.remaining_length_enc,
                          &conn->out_packet.remaining_length_enc_bytes,
                          conn->out_packet.remaining_length);
  if(conn->out_packet.remaining_length_enc_bytes > 4) {
    call_event(conn, MQTT_EVENT_PROTOCOL_ERROR, NULL);
    PRINTF("MQTT - Error, remaining length > 4 bytes\n");
    PT_EXIT(pt);
  }

  /* Write Fixed Header */
  PT_MQTT_WRITE_BYTE(conn, conn->out_packet.fhdr);
  PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->out_packet.remaining_length_enc,
                      conn->out_packet.remaining_length_enc_bytes);
  /* Write Variable Header */
  PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid << 8));
  PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.mid & 0x00FF));
  /* Write Payload */
  PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length >> 8));
  PT_MQTT_WRITE_BYTE(conn, (conn->out_packet.topic_length & 0x00FF));
  PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->out_packet.topic,
                      conn->out_packet.topic_length);

  /* Send out buffer */
  send_out_buffer(conn);
  timer_set(&conn->t, RESPONSE_WAIT_TIMEOUT);

  /* Wait for UNSUBACK */
  reset_packet(&conn->in_packet);
  PT_WAIT_UNTIL(pt, conn->out_packet.qos_state == MQTT_QOS_STATE_GOT_ACK ||
                timer_expired(&conn->t));

  if(timer_expired(&conn->t)) {
    DBG("Timeout waiting for UNSUBACK\n");
  }

  reset_packet(&conn->in_packet);

  /* This is clear after the entire transaction is complete */
  conn->out_queue_full = 0;

  DBG("MQTT - Done writing subscribe message to out buffer!\n");

  PT_END(pt);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(connect_pt(struct pt *pt, struct mqtt_connection *conn))
{
  PT_BEGIN(pt);

  DBG("MQTT - Sending CONNECT message...\n");

  /* Set up FHDR */
  conn->out_packet.fhdr = MQTT_FHDR_MSG_TYPE_CONNECT;
  conn->out_packet.remaining_length = 0;
  conn->out_packet.remaining_length += MQTT_CONNECT_VHDR_FLAGS_SIZE;
  conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->client_id);
  conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->credentials.username);
  conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->credentials.password);
  conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->will.topic);
  conn->out_packet.remaining_length += MQTT_STRING_LENGTH(&conn->will.message);
  encode_remaining_length(conn->out_packet.remaining_length_enc,
                          &conn->out_packet.remaining_length_enc_bytes,
                          conn->out_packet.remaining_length);
  if(conn->out_packet.remaining_length_enc_bytes > 4) {
    call_event(conn, MQTT_EVENT_PROTOCOL_ERROR, NULL);
    PRINTF("MQTT - Error, remaining length > 4 bytes\n");
    PT_EXIT(pt);
  }

  /* Write Fixed Header */
  PT_MQTT_WRITE_BYTE(conn, conn->out_packet.fhdr);
  PT_MQTT_WRITE_BYTES(conn,
                      conn->out_packet.remaining_length_enc,
                      conn->out_packet.remaining_length_enc_bytes);
  PT_MQTT_WRITE_BYTE(conn, 0);
  PT_MQTT_WRITE_BYTE(conn, 6);
  PT_MQTT_WRITE_BYTES(conn, (uint8_t *)MQTT_PROTOCOL_NAME, 6);
  PT_MQTT_WRITE_BYTE(conn, MQTT_PROTOCOL_VERSION);
  PT_MQTT_WRITE_BYTE(conn, conn->connect_vhdr_flags);
  PT_MQTT_WRITE_BYTE(conn, (conn->keep_alive >> 8));
  PT_MQTT_WRITE_BYTE(conn, (conn->keep_alive & 0x00FF));
  PT_MQTT_WRITE_BYTE(conn, conn->client_id.length << 8);
  PT_MQTT_WRITE_BYTE(conn, conn->client_id.length & 0x00FF);
  PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->client_id.string,
                      conn->client_id.length);
  if(conn->connect_vhdr_flags & MQTT_VHDR_WILL_FLAG) {
    PT_MQTT_WRITE_BYTE(conn, conn->will.topic.length << 8);
    PT_MQTT_WRITE_BYTE(conn, conn->will.topic.length & 0x00FF);
    PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->will.topic.string,
                        conn->will.topic.length);
    PT_MQTT_WRITE_BYTE(conn, conn->will.message.length << 8);
    PT_MQTT_WRITE_BYTE(conn, conn->will.message.length & 0x00FF);
    PT_MQTT_WRITE_BYTES(conn, (uint8_t *)conn->will.message.string,
                        conn->will.message.length);
    DBG("MQTT - Setting will topic to '%s' %u bytes and message to '%s' %u bytes\n",
        conn->will.topic.string,
        conn->will.topic.length,
        conn->will.message.string,
        conn->will.message.length);
  }
  if(conn->connect_vhdr_flags & MQTT_VHDR_USERNAME_FLAG) {
    PT_MQTT_WRITE_BYTE(conn, conn->credentials.username.length << 8);
    PT_MQTT_WRITE_BYTE(conn, conn->credentials.username.length & 0x00FF);
    PT_MQTT_WRITE_BYTES(conn,
                        (uint8_t *)conn->credentials.username.string,
                        conn->credentials.username.length);
  }
  if(conn->connect_vhdr_flags & MQTT_VHDR_PASSWORD_FLAG) {
    PT_MQTT_WRITE_BYTE(conn, conn->credentials.password.length << 8);
    PT_MQTT_WRITE_BYTE(conn, conn->credentials.password.length & 0x00FF);
    PT_MQTT_WRITE_BYTES(conn,
                        (uint8_t *)conn->credentials.password.string,
                        conn->credentials.password.length);
  }

  /* Send out buffer */
  send_out_buffer(conn);
  conn->state = MQTT_CONN_STATE_CONNECTING_TO_BROKER;

  timer_set(&conn->t, RESPONSE_WAIT_TIMEOUT);

  /* Wait for CONNACK */
  reset_packet(&conn->in_packet);
  PT_WAIT_UNTIL(pt, conn->out_packet.qos_state == MQTT_QOS_STATE_GOT_ACK ||
                timer_expired(&conn->t));
  if(timer_expired(&conn->t)) {
    DBG("Timeout waiting for CONNACK\n");
    /* We stick to the letter of the spec here: Tear the connection down */
    mqtt_disconnect(conn);
  }
  reset_packet(&conn->in_packet);

  DBG("MQTT - Done sending CONNECT\n");

#if DEBUG_MQTT == 1
  DBG("MQTT - CONNECT message sent: \n");
  uint16_t i;
  for(i = 0; i < (conn->out_buffer_ptr - conn->out_buffer); i++) {
    DBG("%02X ", conn->out_buffer[i]);
  }
  DBG("\n");
#endif

  PT_END(pt);
}
Beispiel #22
0
static int applehttp_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    AppleHTTPContext *c = s->priv_data;
    int ret, i, minvariant = -1, first = 1, needed = 0, changed = 0,
        variants = 0;

    /* Recheck the discard flags - which streams are desired at the moment */
    for (i = 0; i < c->n_variants; i++)
        c->variants[i]->needed = 0;
    for (i = 0; i < s->nb_streams; i++) {
        AVStream *st = s->streams[i];
        struct variant *var = c->variants[s->streams[i]->id];
        if (st->discard < AVDISCARD_ALL) {
            var->needed = 1;
            needed++;
        }
        /* Copy the discard flag to the chained demuxer, to indicate which
         * streams are desired. */
        var->ctx->streams[i - var->stream_offset]->discard = st->discard;
    }
    if (!needed)
        return AVERROR_EOF;
start:
    for (i = 0; i < c->n_variants; i++) {
        struct variant *var = c->variants[i];
        /* Close unneeded streams, open newly requested streams */
        if (var->pb && !var->needed) {
            av_log(s, AV_LOG_DEBUG,
                   "Closing variant stream %d, no longer needed\n", i);
            av_free_packet(&var->pkt);
            reset_packet(&var->pkt);
            url_fclose(var->pb);
            var->pb = NULL;
            changed = 1;
        } else if (!var->pb && var->needed) {
            if (first)
                av_log(s, AV_LOG_DEBUG, "Opening variant stream %d\n", i);
            if (first && !c->finished)
                if ((ret = parse_playlist(c, var->url, var, NULL)) < 0)
                    return ret;
            ret = open_variant(c, var, first);
            if (ret < 0)
                return ret;
            changed = 1;
        }
        /* Count the number of open variants */
        if (var->pb)
            variants++;
        /* Make sure we've got one buffered packet from each open variant
         * stream */
        if (var->pb && !var->pkt.data) {
            ret = av_read_frame(var->ctx, &var->pkt);
            if (ret < 0) {
                if (!url_feof(var->pb))
                    return ret;
                reset_packet(&var->pkt);
            }
        }
        /* Check if this stream has the packet with the lowest dts */
        if (var->pkt.data) {
            if (minvariant < 0 ||
                var->pkt.dts < c->variants[minvariant]->pkt.dts)
                minvariant = i;
        }
    }
    if (first && changed)
        av_log(s, AV_LOG_INFO, "Receiving %d variant streams\n", variants);
    /* If we got a packet, return it */
    if (minvariant >= 0) {
        *pkt = c->variants[minvariant]->pkt;
        pkt->stream_index += c->variants[minvariant]->stream_offset;
        reset_packet(&c->variants[minvariant]->pkt);
        c->last_packet_dts = pkt->dts;
        return 0;
    }
    /* No more packets - eof reached in all variant streams, close the
     * current segments. */
    for (i = 0; i < c->n_variants; i++) {
        struct variant *var = c->variants[i];
        if (var->pb) {
            url_fclose(var->pb);
            var->pb = NULL;
        }
    }
    /* Indicate that we're opening the next segment, not opening a new
     * variant stream in parallel, so we shouldn't try to skip ahead. */
    first = 0;
    c->cur_seq_no++;
reload:
    if (!c->finished) {
        /* If this is a live stream and target_duration has elapsed since
         * the last playlist reload, reload the variant playlists now. */
        int64_t now = av_gettime();
        if (now - c->last_load_time >= c->target_duration*1000000) {
            c->max_start_seq = 0;
            c->min_end_seq   = INT_MAX;
            for (i = 0; i < c->n_variants; i++) {
                struct variant *var = c->variants[i];
                if (var->needed) {
                    if ((ret = parse_playlist(c, var->url, var, NULL)) < 0)
                        return ret;
                    c->max_start_seq = FFMAX(c->max_start_seq,
                                             var->start_seq_no);
                    c->min_end_seq   = FFMIN(c->min_end_seq,
                                             var->start_seq_no + var->n_segments);
                }
            }
        }
    }
    if (c->cur_seq_no < c->max_start_seq) {
        av_log(NULL, AV_LOG_WARNING,
               "skipping %d segments ahead, expired from playlists\n",
               c->max_start_seq - c->cur_seq_no);
        c->cur_seq_no = c->max_start_seq;
    }
    /* If more segments exit, open the next one */
    if (c->cur_seq_no < c->min_end_seq)
        goto start;
    /* We've reached the end of the playlists - return eof if this is a
     * non-live stream, wait until the next playlist reload if it is live. */
    if (c->finished)
        return AVERROR_EOF;
    while (av_gettime() - c->last_load_time < c->target_duration*1000000) {
        if (url_interrupt_cb())
            return AVERROR(EINTR);
        usleep(100*1000);
    }
    /* Enough time has elapsed since the last reload */
    goto reload;
}
Beispiel #23
0
static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    HLSContext *c = s->priv_data;
    int ret, i, minplaylist = -1;

    if (c->first_packet) {
        recheck_discard_flags(s, 1);
        c->first_packet = 0;
    }

start:
    c->end_of_segment = 0;
    for (i = 0; i < c->n_playlists; i++) {
        struct playlist *pls = c->playlists[i];
        /* Make sure we've got one buffered packet from each open playlist
         * stream */
        if (pls->needed && !pls->pkt.data) {
            while (1) {
                int64_t ts_diff;
                AVStream *st;
                ret = av_read_frame(pls->ctx, &pls->pkt);
                if (ret < 0) {
                    if (!url_feof(&pls->pb) && ret != AVERROR_EOF)
                        return ret;
                    reset_packet(&pls->pkt);
                    break;
                } else {
                    if (c->first_timestamp == AV_NOPTS_VALUE &&
                        pls->pkt.dts       != AV_NOPTS_VALUE)
                        c->first_timestamp = av_rescale_q(pls->pkt.dts,
                            pls->ctx->streams[pls->pkt.stream_index]->time_base,
                            AV_TIME_BASE_Q);
                }

                if (c->seek_timestamp == AV_NOPTS_VALUE)
                    break;

                if (pls->pkt.dts == AV_NOPTS_VALUE) {
                    c->seek_timestamp = AV_NOPTS_VALUE;
                    break;
                }

                st = pls->ctx->streams[pls->pkt.stream_index];
                ts_diff = av_rescale_rnd(pls->pkt.dts, AV_TIME_BASE,
                                         st->time_base.den, AV_ROUND_DOWN) -
                          c->seek_timestamp;
                if (ts_diff >= 0 && (c->seek_flags  & AVSEEK_FLAG_ANY ||
                                     pls->pkt.flags & AV_PKT_FLAG_KEY)) {
                    c->seek_timestamp = AV_NOPTS_VALUE;
                    break;
                }
                av_free_packet(&pls->pkt);
                reset_packet(&pls->pkt);
            }
        }
        /* Check if this stream still is on an earlier segment number, or
         * has the packet with the lowest dts */
        if (pls->pkt.data) {
            struct playlist *minpls = minplaylist < 0 ?
                                     NULL : c->playlists[minplaylist];
            if (minplaylist < 0 || pls->cur_seq_no < minpls->cur_seq_no) {
                minplaylist = i;
            } else if (pls->cur_seq_no == minpls->cur_seq_no) {
                int64_t dts     =    pls->pkt.dts;
                int64_t mindts  = minpls->pkt.dts;
                AVStream *st    =    pls->ctx->streams[pls->pkt.stream_index];
                AVStream *minst = minpls->ctx->streams[minpls->pkt.stream_index];

                if (dts == AV_NOPTS_VALUE) {
                    minplaylist = i;
                } else if (mindts != AV_NOPTS_VALUE) {
                    if (st->start_time    != AV_NOPTS_VALUE)
                        dts    -= st->start_time;
                    if (minst->start_time != AV_NOPTS_VALUE)
                        mindts -= minst->start_time;

                    if (av_compare_ts(dts, st->time_base,
                                      mindts, minst->time_base) < 0)
                        minplaylist = i;
                }
            }
        }
    }
    if (c->end_of_segment) {
        if (recheck_discard_flags(s, 0))
            goto start;
    }
    /* If we got a packet, return it */
    if (minplaylist >= 0) {
        *pkt = c->playlists[minplaylist]->pkt;
        pkt->stream_index += c->playlists[minplaylist]->stream_offset;
        reset_packet(&c->playlists[minplaylist]->pkt);
        return 0;
    }
    return AVERROR_EOF;
}