{"action":"closed","issue":{"url":"https://api.github.com/repos/Azure/azure-iot-sdk-c/issues/211","repository_url":"https://api.github.com/repos/Azure/azure-iot-sdk-c","labels_url":"https://api.github.com/repos/Azure/azure-iot-sdk-c/issues/211/labels{/name}","comments_url":"https://api.github.com/repos/Azure/azure-iot-sdk-c/issues/211/comments","events_url":"https://api.github.com/repos/Azure/azure-iot-sdk-c/issues/211/events","html_url":"https://github.com/Azure/azure-iot-sdk-c/issues/211","id":251179131,"number":211,"title":"Upload large file to IoTHub blob storage with azure-iot-sdk-c","user":{"login":"GeraldSchmitt","id":30494109,"avatar_url":"https://avatars2.githubusercontent.com/u/30494109?v=4","gravatar_id":"","url":"https://api.github.com/users/GeraldSchmitt","html_url":"https://github.com/GeraldSchmitt","followers_url":"https://api.github.com/users/GeraldSchmitt/followers","following_url":"https://api.github.com/users/GeraldSchmitt/following{/other_user}","gists_url":"https://api.github.com/users/GeraldSchmitt/gists{/gist_id}","starred_url":"https://api.github.com/users/GeraldSchmitt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GeraldSchmitt/subscriptions","organizations_url":"https://api.github.com/users/GeraldSchmitt/orgs","repos_url":"https://api.github.com/users/GeraldSchmitt/repos","events_url":"https://api.github.com/users/GeraldSchmitt/events{/privacy}","received_events_url":"https://api.github.com/users/GeraldSchmitt/received_events","type":"User","site_admin":false},"labels":[{"id":461734078,"url":"https://api.github.com/repos/Azure/azure-iot-sdk-c/labels/enhancement","name":"enhancement","color":"1d76db","default":true}],"state":"closed","locked":false,"assignee":{"login":"ewertons","id":12401690,"avatar_url":"https://avatars0.githubusercontent.com/u/12401690?v=4","gravatar_id":"","url":"https://api.github.com/users/ewertons","html_url":"https://github.com/ewertons","followers_url":"https://api.github.com/users/ewertons/followers","following_url":"https://api.github.com/users/ewertons/following{/other_user}","gists_url":"https://api.github.com/users/ewertons/gists{/gist_id}","starred_url":"https://api.github.com/users/ewertons/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ewertons/subscriptions","organizations_url":"https://api.github.com/users/ewertons/orgs","repos_url":"https://api.github.com/users/ewertons/repos","events_url":"https://api.github.com/users/ewertons/events{/privacy}","received_events_url":"https://api.github.com/users/ewertons/received_events","type":"User","site_admin":false},"assignees":[{"login":"ewertons","id":12401690,"avatar_url":"https://avatars0.githubusercontent.com/u/12401690?v=4","gravatar_id":"","url":"https://api.github.com/users/ewertons","html_url":"https://github.com/ewertons","followers_url":"https://api.github.com/users/ewertons/followers","following_url":"https://api.github.com/users/ewertons/following{/other_user}","gists_url":"https://api.github.com/users/ewertons/gists{/gist_id}","starred_url":"https://api.github.com/users/ewertons/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ewertons/subscriptions","organizations_url":"https://api.github.com/users/ewertons/orgs","repos_url":"https://api.github.com/users/ewertons/repos","events_url":"https://api.github.com/users/ewertons/events{/privacy}","received_events_url":"https://api.github.com/users/ewertons/received_events","type":"User","site_admin":false},{"login":"markrad","id":12402055,"avatar_url":"https://avatars2.githubusercontent.com/u/12402055?v=4","gravatar_id":"","url":"https://api.github.com/users/markrad","html_url":"https://github.com/markrad","followers_url":"https://api.github.com/users/markrad/followers","following_url":"https://api.github.com/users/markrad/following{/other_user}","gists_url":"https://api.github.com/users/markrad/gists{/gist_id}","starred_url":"https://api.github.com/users/markrad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/markrad/subscriptions","organizations_url":"https://api.github.com/users/markrad/orgs","repos_url":"https://api.github.com/users/markrad/repos","events_url":"https://api.github.com/users/markrad/events{/privacy}","received_events_url":"https://api.github.com/users/markrad/received_events","type":"User","site_admin":false}],"milestone":null,"comments":8,"created_at":"2017-08-18T08:45:14Z","updated_at":"2018-02-01T16:30:46Z","closed_at":"2018-02-01T16:30:46Z","author_association":"CONTRIBUTOR","body":"\r\n### What do we need?\r\n\r\nFrom a device using the *azure-iot-sdk-c*, we want to upload a big file. \r\nThis file can't fit in memory (or on the disk/flash), but is generated block by block by the device.\r\nAll these blocks should be uploaded one after the other on the cloud, and the corresponding \r\nfile should be reconstructed.\r\n\r\nWe wish to expose the following  interface to the device, or something similar:\r\n\r\n```C\r\nLARGEFILE_HANDLE LARGEFILE_open(const IOTHUB_CLIENT_CONFIG* config,\r\n                                const char* filename);\r\n\r\nIOTHUB_CLIENT_RESULT LARGEFILE_write(LARGEFILE_HANDLE handle, \r\n                                     const unsigned char* source, \r\n                                     size_t size);\r\n\r\nvoid LARGEFILE_close(LARGEFILE_HANDLE handle);\r\n```\r\nIn other words : `fopen, fwrite, fclose`\r\n\r\nAll the function calls should be synchronous.\r\nIt would be the client responsibility to call as many `LARGEFILE_write` as necessary and check\r\nthe returned value in case of failure.\r\nIt would probably fit in the `_LL_` interface.\r\n\r\n### How could we do it?\r\n\r\nA similar process already exists in the sdk: the **UploadToBlob** functionnality,\r\nexposed in **iothub_client_ll_uploadtoblob.h**.\r\nThe difference with our need is that the blocks are generated from the source buffer inside \r\nthe function `Blob_UploadFromSasUri` (if the buffer is bigger than 64MB), \r\nin the file **blob.c**.\r\n\r\nSo basically, we would need to use nearly the same sequence of operations as a typical use of UploadToBlob, \r\nbut expose a different interface.\r\n\r\nWe feel that there are mainly two ways of doing this:\r\n\r\n+ Write a new module independent from **UploadToBlob**\r\n  + *pros*: UploadToBlob left untouched\r\n  + *cons*: Code dupplication\r\n+ Extend the module **UploadToBlob**\r\n  + *pros*: Less code dupplication\r\n  + *cons*: Refactor UploadToBlob. We probably have to split existing function and \r\n    add more ressource handles, making the code more complex\r\n\r\n### What now?\r\n\r\n+ We could implement this outside the *azure-iot-sdk-c*, \r\n  but we think it would be easier and more logical to have *azure-iot-sdk-c* implement it.\r\n+ We are ready to modify the *azure-iot-sdk-c* ourselves and make a pull request, \r\n  but before doing that, we want to know how to improve our chances to get the PR accepted.\r\n\r\n#38 #contribution\r\n"}}
{"actor":{"display_login":"jspaith"}}