Beispiel #1
0
/* read an array */
static amf0_data * amf0_array_read(read_proc_t read_proc, void * user_data) {
    size_t i;
    amf0_data * element;
    amf0_data * data = amf0_array_new();
    if (data != NULL) {
        uint32_t array_size;
        if (read_proc(&array_size, sizeof(uint32_t), user_data) == sizeof(uint32_t)) {
            array_size = swap_uint32(array_size);
            
            for (i = 0; i < array_size; ++i) {
                element = amf0_data_read(read_proc, user_data);

                if (element != NULL) {
                    if (amf0_array_push(data, element) == NULL) {
                        amf0_data_free(element);
                        amf0_data_free(data);
                        return NULL;
                    }
                }
                else {
                    amf0_data_free(data);
                    return NULL;
                }
            }
        }
        else {
            amf0_data_free(data);
            return NULL;
        }
    }
    return data;
}
Beispiel #2
0
/* read an object */
static amf0_data * amf0_object_read(read_proc_t read_proc, void * user_data) {
    amf0_data * data = amf0_object_new();
    if (data != NULL) {
        amf0_data * name;
        amf0_data * element;
        while (1) {
            name = amf0_string_read(read_proc, user_data);
            if (name != NULL) {
                element = amf0_data_read(read_proc, user_data);
                if (element != NULL) {
                    if (amf0_object_add(data, (char *)amf0_string_get_uint8_ts(name), element) == NULL) {
                        amf0_data_free(name);
                        amf0_data_free(element);
                        amf0_data_free(data);
                        return NULL;
                    }
                }
                else {
                    amf0_data_free(name);
                    break;
                }
            }
            else {
                /* invalid name: error */
                amf0_data_free(data);
                return NULL;
            }
        }
    }
    return data;
}
Beispiel #3
0
/* static */
    Message Message::CreateStream() {
        uint8_t buf[4096];
        size_t len;
        Message msg;
        amf0_data *data;

        msg.write_string("createStream");

        data = amf0_number_new(2);
        len = amf0_data_buffer_write(data, buf, 4096);
        msg.body_.insert(msg.body_.end(), buf, buf + len);
        amf0_data_free(data);

        data = amf0_null_new();
        len = amf0_data_buffer_write(data, buf, 4096);
        msg.body_.insert(msg.body_.end(), buf, buf + len);
        amf0_data_free(data);

        msg.csid_ = 3;
        msg.timestamp_ = 0;
        msg.type_ = COMMAND_AMF0;  /* Command AMF0 */
        msg.stream_id_ = 0;
        msg.length_ = msg.body_.size();
        return msg;
    }
Beispiel #4
0
    Message Message::Play(std::string key) {
        uint8_t buf[4096];
        size_t len;
        Message msg;
        amf0_data *data;

        msg.write_string("play");

        data = amf0_number_new(3);
        len = amf0_data_buffer_write(data, buf, 4096);
        msg.body_.insert(msg.body_.end(), buf, buf + len);
        amf0_data_free(data);

        data = amf0_null_new();
        len = amf0_data_buffer_write(data, buf, 4096);
        msg.body_.insert(msg.body_.end(), buf, buf + len);
        amf0_data_free(data);

        msg.write_string(key);

        data = amf0_number_new(-2000);
        len = amf0_data_buffer_write(data, buf, 4096);
        msg.body_.insert(msg.body_.end(), buf, buf + len);
        amf0_data_free(data);

        msg.csid_ = 8;
        msg.timestamp_ = 0;
        msg.type_ = COMMAND_AMF0;  /* AMF 0 */
        msg.stream_id_ = 1;
        msg.length_ = msg.body_.size();
        return msg;
    }
Beispiel #5
0
/*static*/
    Message Message::Connect(std::string app, int rpc_number) {
        uint8_t buf[4096];
        size_t len;
        Message msg;
        amf0_data *data;

        msg.write_string("connect");

        data = amf0_number_new(rpc_number);
        len = amf0_data_buffer_write(data, buf, 4096);
        msg.body_.insert(msg.body_.end(), buf, buf + len);
        amf0_data_free(data);

        data = amf0_object_new();
        amf0_object_add(data, "app", amf0_str(app.c_str()));
        amf0_object_add(data, "type", amf0_str("nonprivate"));
        amf0_object_add(data, "flashVer", amf0_str("FMLE/3.0 (compatible; obs-studio/0.14.2; FMSc/1.0)"));
        amf0_object_add(data, "tcUrl", amf0_str("rtmp://live.hkstv.hk.lxdns.com:1935/live"));
        amf0_object_add(data, "capabilities", amf0_number_new(15));
        amf0_object_add(data, "audioCodecs", amf0_number_new(4071));
        amf0_object_add(data, "videoCodecs", amf0_number_new(252));
        amf0_object_add(data, "videoFunction", amf0_number_new(1));
        len = amf0_data_buffer_write(data, buf, 4096);
        msg.body_.insert(msg.body_.end(), buf, buf + len);
        amf0_data_free(data);

        msg.csid_ = 3;
        msg.type_ = COMMAND_AMF0;  /* Command AMF0 */
        msg.stream_id_ = 0;
        msg.length_ = msg.body_.size();
        return msg;
    }
Beispiel #6
0
amf0_data * amf0_object_add(amf0_data * data, const char * name, amf0_data * element) {
  if (data != NULL) {
    amf0_data *str_name = amf0_str(name);
    if (amf0_list_push(&data->u.list_data, str_name) != NULL) {
      if (amf0_list_push(&data->u.list_data, element) != NULL) {
	return element;
      }
      else {
	amf0_data_free(amf0_list_pop(&data->u.list_data));
      }
    }
    amf0_data_free(str_name);
  }
  return NULL;
}
Beispiel #7
0
    size_t Message::write_string(std::string str) {
        uint8_t buf[4096];
        size_t len;
        amf0_data *data = amf0_str(str.c_str());
        len = amf0_data_buffer_write(data, buf, 4096);
        body_.insert(body_.end(), buf, buf + len);
        amf0_data_free(data);

        return len;
    }
Beispiel #8
0
static void amf0_list_clear(amf0_list * list) {
    amf0_node * tmp;
    amf0_node * node = list->first_element;
    while (node != NULL) {
        amf0_data_free(node->data);
        tmp = node;
        node = node->next;
        free(tmp);
    }
    list->size = 0;
}
Beispiel #9
0
/* read an array */
static amf0_data * amf0_array_read(read_proc_t read_proc, void * user_data) {
    size_t i;
    amf0_data * element;
    uint8_t error_code;
    amf0_data * data;
    uint32_t array_size;

    data = amf0_array_new();
    if (data == NULL) {
        return NULL;
    }

    if (read_proc(&array_size, sizeof(uint32_t), user_data) < sizeof(uint32_t)) {
        amf0_data_free(data);
        return amf0_data_error(AMF0_ERROR_EOF);
    }

    array_size = swap_uint32(array_size);

    for (i = 0; i < array_size; ++i) {
        element = amf0_data_read(read_proc, user_data);
        error_code = amf0_data_get_error(element);
        if (error_code != AMF0_ERROR_OK) {
            amf0_data_free(element);
            amf0_data_free(data);
            return amf0_data_error(error_code);
        }

        if (amf0_array_push(data, element) == NULL) {
            amf0_data_free(element);
            amf0_data_free(data);
            return NULL;
        }
    }

    return data;
}
Beispiel #10
0
amf0_data * amf0_object_delete(amf0_data * data, const char * name) {
    if (data != NULL) {
        amf0_node * node = amf0_list_first(&data->list_data);
        while (node != NULL) {
            node = node->next;
            if (strncmp((char*)(node->data->string_data.mbstr), name, (size_t)(node->data->string_data.size)) == 0) {
                amf0_node * data_node = node->next;
                amf0_data_free(amf0_list_delete(&data->list_data, node));
                return amf0_list_delete(&data->list_data, data_node);
            }
            else {
                node = node->next;
            }
        }
    }
    return NULL;
}
Beispiel #11
0
/* string functions */
amf0_data * amf0_string_new(uint8_t * str, uint16_t size) {
    amf0_data * data = amf0_data_new(AMF0_TYPE_STRING);
    if (data != NULL) {
        data->string_data.size = size;
        data->string_data.mbstr = (uint8_t*)calloc(size+1, sizeof(uint8_t));
        if (data->string_data.mbstr != NULL) {
            if (size > 0) {
                memcpy(data->string_data.mbstr, str, size);
            }
        }
        else {
            amf0_data_free(data);
            return NULL;
        }
    }
    return data;
}
Beispiel #12
0
amf0_data * amf0_object_set(amf0_data * data, const char * name, amf0_data * element) {
    if (data != NULL) {
        amf0_node * node = amf0_list_first(&(data->list_data));
        while (node != NULL) {
            if (strncmp((char*)(node->data->string_data.mbstr), name, (size_t)(node->data->string_data.size)) == 0) {
                node = node->next;
                if (node != NULL && node->data != NULL) {
                    amf0_data_free(node->data);
                    node->data = element;
                    return element;
                }
            }
            /* we have to skip the element data to reach the next name */
            node = node->next->next;
        }
    }
    return NULL;
}
Beispiel #13
0
/* read an associative array */
static amf0_data * amf0_associative_array_read(read_proc_t read_proc, void * user_data) {
    amf0_data * data = amf0_associative_array_new();
    if (data != NULL) {
        amf0_data * name;
        amf0_data * element;
        uint32_t size;
        if (read_proc(&size, sizeof(uint32_t), user_data) == sizeof(uint32_t)) {
            /* we ignore the 32 bits array size marker */
            while(1) {
                name = amf0_string_read(read_proc, user_data);
                if (name != NULL) {
                    element = amf0_data_read(read_proc, user_data);
                    if (element != NULL) {
                        if (amf0_associative_array_add(data, (char *)amf0_string_get_uint8_ts(name), element) == NULL) {
                            amf0_data_free(name);
                            amf0_data_free(element);
                            amf0_data_free(data);
                            return NULL;
                        }
                    }
                    else {
                        amf0_data_free(name);
                        break;
                    }
                }
                else {
                    /* invalid name: error */
                    amf0_data_free(data);
                    return NULL;
                }
            }
        }
        else {
            amf0_data_free(data);
            return NULL;
        }
    }
    return data;
}
Beispiel #14
0
/* read an associative array */
static amf0_data * amf0_associative_array_read(read_proc_t read_proc, void * user_data) {
    amf0_data * name;
    amf0_data * element;
    uint32_t size;
    uint8_t error_code;
    amf0_data * data;

    data = amf0_associative_array_new();
    if (data == NULL) {
        return NULL;
    }

    /* we ignore the 32 bits array size marker */
    if (read_proc(&size, sizeof(uint32_t), user_data) < sizeof(uint32_t)) {
        amf0_data_free(data);
        return amf0_data_error(AMF0_ERROR_EOF);
    }

    while(1) {
        name = amf0_string_read(read_proc, user_data);
        error_code = amf0_data_get_error(name);
        if (error_code != AMF0_ERROR_OK) {
            /* invalid name: error */
            amf0_data_free(name);
            amf0_data_free(data);
            return amf0_data_error(error_code);
        }

        element = amf0_data_read(read_proc, user_data);
        error_code = amf0_data_get_error(element);

        if (amf0_string_get_size(name) == 0 || error_code == AMF0_ERROR_END_TAG || error_code == AMF0_ERROR_UNKNOWN_TYPE) {
            /* end tag or unknown element: end of data, exit loop */
            amf0_data_free(name);
            amf0_data_free(element);
            break;
        }
        else if (error_code != AMF0_ERROR_OK) {
            amf0_data_free(name);
            amf0_data_free(data);
            amf0_data_free(element);
            return amf0_data_error(error_code);
        }

        if (amf0_associative_array_add(data, (char *)amf0_string_get_bytes(name), element) == NULL) {
            amf0_data_free(name);
            amf0_data_free(element);
            amf0_data_free(data);
            return NULL;
        }
        else {
            amf0_data_free(name);
        }
    }

    return data;
}
Beispiel #15
0
/* read an object */
static amf0_data * amf0_object_read(read_proc_t read_proc, void * user_data) {
    amf0_data * name;
    amf0_data * element;
    uint8_t error_code;
    amf0_data * data;

    data = amf0_object_new();
    if (data == NULL) {
        return NULL;
    }

    while (1) {
        name = amf0_string_read(read_proc, user_data);
        error_code = amf0_data_get_error(name);
        if (error_code != AMF0_ERROR_OK) {
            /* invalid name: error */
            amf0_data_free(name);
            amf0_data_free(data);
            return amf0_data_error(error_code);
        }

        element = amf0_data_read(read_proc, user_data);
        error_code = amf0_data_get_error(element);
        if (error_code == AMF0_ERROR_END_TAG || error_code == AMF0_ERROR_UNKNOWN_TYPE) {
            /* end tag or unknown element: end of data, exit loop */
            amf0_data_free(name);
            amf0_data_free(element);
            break;
        }
        else if (error_code != AMF0_ERROR_OK) {
            amf0_data_free(name);
            amf0_data_free(data);
            amf0_data_free(element);
            return amf0_data_error(error_code);
        }

        if (amf0_object_add(data, (char *)amf0_string_get_bytes(name), element) == NULL) {
            amf0_data_free(name);
            amf0_data_free(element);
            amf0_data_free(data);
            return NULL;
        }
        else {
            amf0_data_free(name);
        }
    }

    return data;
}