board_init(ssb_to_app_table.ssb_to_application_flash_id, ssb_to_app_table.ssb_to_application_flash_unique_id);
+ //cywee 烧写密钥
+ //reburn_second_dev();
+
service_init();
thread_pri_init();
{\r
PRINT("thread_main start "NEWLINE);\r
unused(unused);\r
+\r
rc_calibration_func_notify();\r
bt_acore_btc_ipc_receive_init();\r
uapi_pm_control(PM_BT_POWER_UP_AND_RUN);\r
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AlarmClockModel::AlarmPlayerStat playerCtr nullptr");
return OHOS_FAILURE;
}
- playerCtr->SetPlayerCallback(playerCallback);
+ //playerCtr->SetPlayerCallback(playerCallback);
// 申请资源
source = std::make_shared<Source>(uri, header);
if (source.get() == nullptr) {
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-06-07 11:18:25
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2024-06-08 17:28:26
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/producttest/include/testmicrophoneC.h
+ * @Description:
+ *
+ * Copyright (c) 2024 by ${git_name_email}, All Rights Reserved.
+ */
+#ifndef TEST_MICROPHONEC_H
+#define TEST_MICROPHONEC_H
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C"
+{
+#endif
+#endif
+ void microhone_switch(bool isopen);
+ void check_spk(bool isopen);
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif
+#endif
+++ /dev/null
-#ifndef TEST_SPEAKERC_H
-#define TEST_SPEAKERC_H
-
-#ifdef __cplusplus
-#if __cplusplus
-extern "C"
-{
-#endif
-#endif
- int check_speaker(bool isopen);
-#ifdef __cplusplus
-#if __cplusplus
-}
-#endif
-#endif
-#endif
delete Title;
Title=nullptr;
}
+ AlarmClockModel::GetInstance()->AlarmPlayerStop();
delete testmakephoneScrollView;
testmakephoneScrollView=nullptr;
}
uint8_t makphone_falg=0;
- static char *Path= "/user/music/microphone.mp3";
+ static char *Path= "/user/userdata/microphone.mp3";
void testmicrohoneView::buttoncallback()
{
if(button!=NULL)
if(makphone_falg==0)
{
char *args[6] = {0};
- const char *defaultArgs[6] = {"01", "mp3", "16000", "1", "16","/user/music/microphone.mp3"}; // 默认参数数组
+ const char *defaultArgs[6] = {"01", "mp3", "16000", "1", "16","/user/userdata/microphone.mp3"}; // 默认参数数组
for (int i = 0; i < 6; ++i)
{
button->SetText("play");
makphone_falg++;
- FILE *file =fopen("/user/music/microphone.mp3","rb");
+ FILE *file =fopen("/user/userdata/microphone.mp3","rb");
if(file==NULL)
{
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ffffffffffffffffsssssss");
}
return testmakephoneScrollView;
}
+
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+ void microhone_switch(bool isopen)
+ {
+ char *args[6] = {0};
+ const char *defaultArgs[6] = {"01", "mp3", "16000", "1", "16","/user/userdata/microphone.mp3"}; // 默认参数数组
+
+ int32_t argc = 1;
+ uint8_t *argv = (uint8_t*)"stop";
+
+ if(isopen)
+ {
+ for (int i = 0; i < 6; ++i)
+ {
+ args[i] = (char *)malloc(64);
+ sprintf(args[i], "%s", defaultArgs[i]);
+ }
+ AudioCaptureSample(6, (const char **)args);
+ }
+ else
+ {
+ AudioCaptureSample(argc, (const char **)&argv);
+ FILE *file =fopen("/user/userdata/microphone.mp3","rb");
+ if(file==NULL)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ffffffffffffffffsssssss");
+ }
+ fclose(file);
+ }
+ }
+
+ void check_spk(bool isopen)
+ {
+ if(isopen)
+ AlarmClockModel::GetInstance()->testPlayerStart("/user/userdata/microphone.mp3");
+ else
+ AlarmClockModel::GetInstance()->AlarmPlayerStop();
+ }
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+
}
\ No newline at end of file
}
return testSPEAKScrollView;
}
-
- #ifdef __cplusplus
-#if __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-#endif /* __cplusplus */
-
- int check_speaker(bool isopen)
- {
- if(isopen)
- return AlarmClockModel::GetInstance()->AlarmPlayerStart();
- else
- return AlarmClockModel::GetInstance()->AlarmPlayerStop();
- }
-#ifdef __cplusplus
-#if __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* __cplusplus */
}
case BLE_TEST_CMD_SOFT_TEST_SUB_MODE_SPEAKER:\r
if(testitem == 0x01)\r
{\r
-\r
uint8_t send_data= 0;\r
\r
- uapi_check_speaker(1);\r
- \r
+ uapi_microhone_switch(1);\r
+ \r
factorytest_protocol_replymsg(BLE_TEST_CMD_MODE_SOFT_TEST,\r
BLE_TEST_CMD_SOFT_TEST_SUB_MODE_SPEAKER,\r
0x01,\r
\r
uint8_t send_data = 0;\r
\r
- uapi_check_speaker(0);;\r
+ uapi_microhone_switch(0);\r
\r
factorytest_protocol_replymsg(BLE_TEST_CMD_MODE_SOFT_TEST,\r
BLE_TEST_CMD_SOFT_TEST_SUB_MODE_SPEAKER,\r
0x02,\r
&send_data,\r
1);\r
+ } else if(testitem == 0x03)\r
+ {\r
+\r
+ uint8_t send_data = 0;\r
+\r
+ uapi_check_spk(1);\r
+ \r
+ factorytest_protocol_replymsg(BLE_TEST_CMD_MODE_SOFT_TEST,\r
+ BLE_TEST_CMD_SOFT_TEST_SUB_MODE_SPEAKER,\r
+ 0x03,\r
+ &send_data,\r
+ 1);\r
+ } else if(testitem == 0x04)\r
+ {\r
+\r
+ uint8_t send_data = 0;\r
+\r
+ uapi_check_spk(0);\r
+ \r
+ factorytest_protocol_replymsg(BLE_TEST_CMD_MODE_SOFT_TEST,\r
+ BLE_TEST_CMD_SOFT_TEST_SUB_MODE_SPEAKER,\r
+ 0x04,\r
+ &send_data,\r
+ 1);\r
}\r
break;\r
\r
find_library(LIB_PATH_CWM_LIB_DML Lib/CWM_LIB_DML_clang_riscv.a ${CMAKE_CURRENT_SOURCE_DIR})
find_library(LIB_PATH_CWM_LIB Lib/CWM_LIB_clang_riscv.a ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(${TARGET_NAME} PRIVATE -Wl,--whole-archive ${LIB_PATH_CWM_LIB_DML} ${LIB_PATH_CWM_LIB} PRIVATE -Wl,--whole-archive)
-endif()
#target_link_libraries(${TARGET_NAME} PRIVATE -Wl,--whole-archive ${LIB_PATH_CWM_LIB} PRIVATE -Wl,--whole-archive)
-#endif()
+endif()
+
build_component()
int len = 0, ret = 0;\r
\r
impl_prepare(&m_var);\r
+ printf("[reburn_second_dev] Built at %s %s\n", __DATE__, __TIME__);\r
\r
- reburn_log_printf("[reburn_second_dev] Built at %s %s\n", __DATE__, __TIME__);\r
- printf("[reburn_second_dev] Built at \r\n");\r
if (!impl_checkMcuModel()) {\r
- reburn_log_printf("cannot reburn: wrong model\n");\r
printf("cannot reburn: wrong model \r\n");\r
return STS_ERR_WRONG_MODEL;\r
}\r
scl.iData[0] = 1;\r
CWM_SettingControl(SCL_GET_LIB_INFO, &scl);\r
if (scl.iData[5] < 3000) {\r
- reburn_log_printf("%d Not a valid reburn library\n", scl.iData[5]);\r
printf("%d Not a valid reburn library\n", scl.iData[5]);\r
return STS_ERR_INVALID_LIB;\r
}\r
- reburn_log_printf("model:%s version:%d.%d.%d.%d product:%d\n", m_var.chip_name, scl.iData[1], scl.iData[2], scl.iData[3], scl.iData[4], scl.iData[5]);\r
printf("model:%s version:%d.%d.%d.%d product:%d\n", m_var.chip_name, scl.iData[1], scl.iData[2], scl.iData[3], scl.iData[4], scl.iData[5]);\r
\r
impl_sec_env_init();\r
}
#endif
-// int cm__hs1__init(void);
-// int cm__hs1__deinit(void);
-
int cywee_main_dml(void)
{
if (cywee_installized == 1)
}
cywee_installized = 1;
- //reburn_second_dev();
+
int i;
memset(&scl, 0, sizeof(scl));
scl.iData[0] = 1;
${CMAKE_CURRENT_SOURCE_DIR}/custom_cmd_service.c
${CMAKE_CURRENT_SOURCE_DIR}/custom_runtime.c
${CMAKE_CURRENT_SOURCE_DIR}/pdu.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/microtar.c
)
set(PUBLIC_HEADER
#ifdef FD230
#include "soundandvibration/include/SoundAndVibrationVolumeSettingC.h"
#include "networkandcall/include/NetworkAndCallC.h"
-#include "producttest/include/testspeakerC.h"
+#include "producttest/include/testmicrophoneC.h"
#endif
#include <dirent.h>
#include <unistd.h>
#include "custom_utils.h"
#include "cywee_service.h"
+#include "microtar.h"
errcode_t uapi_create_osThread_custom(app_task_definition_t *task_cfg)
{
}
void startup_post_init_task(void)
{
-
PRINT("startup_post_init_task !\r\n");
+
uapi_calendar_recover_date();
+ int ret = uapi_save_exc();
+ if(ret != 0)
+ PRINT("exc file save failed \r\n");
+ else
+ PRINT("exc file save succed \r\n");
+
if(!custom_ble_service_on_flag())
{
stop_custom_ble_service();
taskcfg.create_queue_handle = NULL;
taskcfg.attr.name="startup_post_init_task";
taskcfg.attr.priority = osPriorityNormal;
- taskcfg.attr.stack_size = 0x1000;
+ taskcfg.attr.stack_size = 0x1100;
taskcfg.func = startup_post_init_task;
taskcfg.use_mem = USE_EXTEND_MEM;
struct stat s_buf;
int ret = 0;
+ if(access(folderPath, F_OK) == -1)
+ {
+ PRINT("%s does not exist!!!\r\n", folderPath);
+ return -1;
+ }
+
dir = opendir(folderPath);
if (dir == NULL)
{
}
}
+int uapi_save_exc(void)
+{
+ const char *folderPath = "/user/exc";
+ const char *tarPath = "/user/tar";
+ const char *tarfilePath = "/user/tar/exc_%d.tar";
+
+ DIR *dir;
+ struct dirent *entry;
+ mtar_t tar;
+ char buffer[1024];
+ size_t bytesRead = 0;
+ FILE *fp;
+ struct stat file_inf;
+ int ret = 0;
+
+ dir = opendir(folderPath);
+ if (dir == NULL)
+ {
+ PRINT("unable to open %s\r\n",folderPath);
+ return -1;
+ }
+
+ if(access(tarPath, F_OK) == -1)
+ {
+ ret = mkdir(tarPath, 0777);
+ if(ret == -1)
+ {
+ PRINT("mkdir %s failed \r\n",tarPath);
+ return -1;
+ }
+ }
+
+ uint32_t timestamp = get_local_timestamp();
+ char *str = (char *)malloc(200);
+ memset_s(str, 200, 0, 200);
+ sprintf(str, tarfilePath, timestamp);
+
+ ret = mtar_open(&tar, str, "w");
+ if (ret != MTAR_ESUCCESS)
+ {
+ PRINT("unable to open/create %s\r\n",str);
+ return -1;
+ }
+
+ while ((entry = readdir(dir)) != NULL)
+ {
+ if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)
+ {
+ char filePath[64];
+ snprintf(filePath, sizeof(filePath), "%s/%s", folderPath, entry->d_name);
+
+ fp = fopen(filePath, "r");
+ if(fp == NULL)
+ {
+ PRINT("uable to open %s\r\n", filePath);
+ return -1;
+ }
+
+ memset(&file_inf, 0, sizeof(file_inf));
+ stat(filePath, &file_inf);
+
+ mtar_write_file_header(&tar, entry->d_name, file_inf.st_size);
+
+ while((bytesRead = fread(buffer, 1, sizeof(buffer), fp)) > 0)
+ {
+ mtar_write_data(&tar, buffer, bytesRead);
+
+ memset(buffer, 0, sizeof(buffer));
+
+ if (bytesRead < 1024 && !feof(fp))
+ continue;
+
+ if (feof(fp))
+ {
+ fclose(fp);
+ break;
+ }
+ }
+ }
+ }
+
+ /* Finalize -- this needs to be the last thing done before closing */
+ mtar_finalize(&tar);
+
+ /* Close archive */
+ mtar_close(&tar);
+ closedir(dir);
+ return ret;
+}
#include "driver/calendar.h"
}
#endif
-int uapi_check_speaker(bool isopen)
+void uapi_microhone_switch(bool isopen)
+{
+ #ifdef FD230
+ microhone_switch(isopen);
+ #endif
+}
+
+void uapi_check_spk(bool isopen)
{
#ifdef FD230
- return check_speaker(isopen);
+ check_spk(isopen);
#endif
}
\ No newline at end of file
void uapi_cywee_time_sync(void);
void uapi_cywee_get_chipinfo(char *databuf,uint8_t len);
void uapi_ppg_get_id(uint8_t *chip_id);
+
+
+void uapi_microhone_switch(bool isopen);
+void uapi_check_spk(bool isopen);
+
#include "custom_utilscpp.h"
--- /dev/null
+/*
+ * Copyright (c) 2017 rxi
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "microtar.h"
+
+typedef struct {
+ char name[100];
+ char mode[8];
+ char owner[8];
+ char group[8];
+ char size[12];
+ char mtime[12];
+ char checksum[8];
+ char type;
+ char linkname[100];
+ char _padding[255];
+} mtar_raw_header_t;
+
+
+static unsigned round_up(unsigned n, unsigned incr) {
+ return n + (incr - n % incr) % incr;
+}
+
+
+static unsigned checksum(const mtar_raw_header_t* rh) {
+ unsigned i;
+ unsigned char *p = (unsigned char*) rh;
+ unsigned res = 256;
+ for (i = 0; i < offsetof(mtar_raw_header_t, checksum); i++)
+ {
+ res += p[i];
+ }
+ for (i = offsetof(mtar_raw_header_t, type); i < sizeof(*rh); i++)
+ {
+ res += p[i];
+ }
+ return res;
+}
+
+
+static int tread(mtar_t *tar, void *data, unsigned size)
+{
+ int err = tar->read(tar, data, size);
+ tar->pos += size;
+ return err;
+}
+
+
+static int twrite(mtar_t *tar, const void *data, unsigned size)
+{
+ int err = tar->write(tar, data, size);
+ tar->pos += size;
+ return err;
+}
+
+
+static int write_null_bytes(mtar_t *tar, int n)
+{
+ int i, err;
+ char nul = '\0';
+ for (i = 0; i < n; i++)
+ {
+ err = twrite(tar, &nul, 1);
+ if (err)
+ {
+ return err;
+ }
+ }
+ return MTAR_ESUCCESS;
+}
+
+
+static int raw_to_header(mtar_header_t *h, const mtar_raw_header_t *rh)
+{
+ unsigned chksum1, chksum2;
+
+ /* If the checksum starts with a null byte we assume the record is NULL */
+ if (*rh->checksum == '\0')
+ {
+ return MTAR_ENULLRECORD;
+ }
+
+ /* Build and compare checksum */
+ chksum1 = checksum(rh);
+ sscanf(rh->checksum, "%o", &chksum2);
+ if (chksum1 != chksum2)
+ {
+ return MTAR_EBADCHKSUM;
+ }
+
+ /* Load raw header into header */
+ sscanf(rh->mode, "%o", &h->mode);
+ sscanf(rh->owner, "%o", &h->owner);
+ sscanf(rh->size, "%o", &h->size);
+ sscanf(rh->mtime, "%o", &h->mtime);
+ h->type = rh->type;
+ strcpy(h->name, rh->name);
+ strcpy(h->linkname, rh->linkname);
+
+ return MTAR_ESUCCESS;
+}
+
+
+static int header_to_raw(mtar_raw_header_t *rh, const mtar_header_t *h)
+{
+ unsigned chksum;
+
+ /* Load header into raw header */
+ memset(rh, 0, sizeof(*rh));
+ sprintf(rh->mode, "%o", h->mode);
+ sprintf(rh->owner, "%o", h->owner);
+ sprintf(rh->size, "%o", h->size);
+ sprintf(rh->mtime, "%o", h->mtime);
+ rh->type = h->type ? h->type : MTAR_TREG;
+ strcpy(rh->name, h->name);
+ strcpy(rh->linkname, h->linkname);
+
+ /* Calculate and write checksum */
+ chksum = checksum(rh);
+ sprintf(rh->checksum, "%06o", chksum);
+ rh->checksum[7] = ' ';
+
+ return MTAR_ESUCCESS;
+}
+
+
+const char* mtar_strerror(int err)
+{
+ switch (err)
+ {
+ case MTAR_ESUCCESS : return "success";
+ case MTAR_EFAILURE : return "failure";
+ case MTAR_EOPENFAIL : return "could not open";
+ case MTAR_EREADFAIL : return "could not read";
+ case MTAR_EWRITEFAIL : return "could not write";
+ case MTAR_ESEEKFAIL : return "could not seek";
+ case MTAR_EBADCHKSUM : return "bad checksum";
+ case MTAR_ENULLRECORD : return "null record";
+ case MTAR_ENOTFOUND : return "file not found";
+ }
+ return "unknown error";
+}
+
+
+static int file_write(mtar_t *tar, const void *data, unsigned size) {
+ unsigned res = fwrite(data, 1, size, tar->stream);
+ return (res == size) ? MTAR_ESUCCESS : MTAR_EWRITEFAIL;
+}
+
+static int file_read(mtar_t *tar, void *data, unsigned size) {
+ unsigned res = fread(data, 1, size, tar->stream);
+ return (res == size) ? MTAR_ESUCCESS : MTAR_EREADFAIL;
+}
+
+static int file_seek(mtar_t *tar, unsigned offset) {
+ int res = fseek(tar->stream, offset, SEEK_SET);
+ return (res == 0) ? MTAR_ESUCCESS : MTAR_ESEEKFAIL;
+}
+
+static int file_close(mtar_t *tar) {
+ fclose(tar->stream);
+ return MTAR_ESUCCESS;
+}
+
+
+int mtar_open(mtar_t *tar, const char *filename, const char *mode) {
+ int err;
+ mtar_header_t h;
+
+ /* Init tar struct and functions */
+ memset(tar, 0, sizeof(*tar));
+ tar->write = file_write;
+ tar->read = file_read;
+ tar->seek = file_seek;
+ tar->close = file_close;
+
+ /* Assure mode is always binary */
+ if ( strchr(mode, 'r') ) mode = "rb";
+ if ( strchr(mode, 'w') ) mode = "wb";
+ if ( strchr(mode, 'a') ) mode = "ab";
+ /* Open file */
+ tar->stream = fopen(filename, mode);
+ if (!tar->stream) {
+ return MTAR_EOPENFAIL;
+ }
+ /* Read first header to check it is valid if mode is `r` */
+ if (*mode == 'r') {
+ err = mtar_read_header(tar, &h);
+ if (err != MTAR_ESUCCESS) {
+ mtar_close(tar);
+ return err;
+ }
+ }
+
+ /* Return ok */
+ return MTAR_ESUCCESS;
+}
+
+
+int mtar_close(mtar_t *tar) {
+ return tar->close(tar);
+}
+
+
+int mtar_seek(mtar_t *tar, unsigned pos) {
+ int err = tar->seek(tar, pos);
+ tar->pos = pos;
+ return err;
+}
+
+
+int mtar_rewind(mtar_t *tar) {
+ tar->remaining_data = 0;
+ tar->last_header = 0;
+ return mtar_seek(tar, 0);
+}
+
+
+int mtar_next(mtar_t *tar) {
+ int err, n;
+ mtar_header_t h;
+ /* Load header */
+ err = mtar_read_header(tar, &h);
+ if (err) {
+ return err;
+ }
+ /* Seek to next record */
+ n = round_up(h.size, 512) + sizeof(mtar_raw_header_t);
+ return mtar_seek(tar, tar->pos + n);
+}
+
+
+int mtar_find(mtar_t *tar, const char *name, mtar_header_t *h) {
+ int err;
+ mtar_header_t header;
+ /* Start at beginning */
+ err = mtar_rewind(tar);
+ if (err) {
+ return err;
+ }
+ /* Iterate all files until we hit an error or find the file */
+ while ( (err = mtar_read_header(tar, &header)) == MTAR_ESUCCESS ) {
+ if ( !strcmp(header.name, name) ) {
+ if (h) {
+ *h = header;
+ }
+ return MTAR_ESUCCESS;
+ }
+ mtar_next(tar);
+ }
+ /* Return error */
+ if (err == MTAR_ENULLRECORD) {
+ err = MTAR_ENOTFOUND;
+ }
+ return err;
+}
+
+
+int mtar_read_header(mtar_t *tar, mtar_header_t *h) {
+ int err;
+ mtar_raw_header_t rh;
+ /* Save header position */
+ tar->last_header = tar->pos;
+ /* Read raw header */
+ err = tread(tar, &rh, sizeof(rh));
+ if (err) {
+ return err;
+ }
+ /* Seek back to start of header */
+ err = mtar_seek(tar, tar->last_header);
+ if (err) {
+ return err;
+ }
+ /* Load raw header into header struct and return */
+ return raw_to_header(h, &rh);
+}
+
+
+int mtar_read_data(mtar_t *tar, void *ptr, unsigned size) {
+ int err;
+ /* If we have no remaining data then this is the first read, we get the size,
+ * set the remaining data and seek to the beginning of the data */
+ if (tar->remaining_data == 0) {
+ mtar_header_t h;
+ /* Read header */
+ err = mtar_read_header(tar, &h);
+ if (err) {
+ return err;
+ }
+ /* Seek past header and init remaining data */
+ err = mtar_seek(tar, tar->pos + sizeof(mtar_raw_header_t));
+ if (err) {
+ return err;
+ }
+ tar->remaining_data = h.size;
+ }
+ /* Read data */
+ err = tread(tar, ptr, size);
+ if (err) {
+ return err;
+ }
+ tar->remaining_data -= size;
+ /* If there is no remaining data we've finished reading and seek back to the
+ * header */
+ if (tar->remaining_data == 0) {
+ return mtar_seek(tar, tar->last_header);
+ }
+ return MTAR_ESUCCESS;
+}
+
+
+int mtar_write_header(mtar_t *tar, const mtar_header_t *h) {
+ mtar_raw_header_t rh;
+ /* Build raw header and write */
+ header_to_raw(&rh, h);
+ tar->remaining_data = h->size;
+ return twrite(tar, &rh, sizeof(rh));
+}
+
+
+int mtar_write_file_header(mtar_t *tar, const char *name, unsigned size) {
+ mtar_header_t h;
+ /* Build header */
+ memset(&h, 0, sizeof(h));
+ strcpy(h.name, name);
+ h.size = size;
+ h.type = MTAR_TREG;
+ h.mode = 0664;
+ /* Write header */
+ return mtar_write_header(tar, &h);
+}
+
+
+int mtar_write_dir_header(mtar_t *tar, const char *name) {
+ mtar_header_t h;
+ /* Build header */
+ memset(&h, 0, sizeof(h));
+ strcpy(h.name, name);
+ h.type = MTAR_TDIR;
+ h.mode = 0775;
+ /* Write header */
+ return mtar_write_header(tar, &h);
+}
+
+
+int mtar_write_data(mtar_t *tar, const void *data, unsigned size) {
+ int err;
+ /* Write data */
+ err = twrite(tar, data, size);
+ if (err) {
+ return err;
+ }
+ tar->remaining_data -= size;
+ /* Write padding if we've written all the data for this file */
+ if (tar->remaining_data == 0) {
+ return write_null_bytes(tar, round_up(tar->pos, 512) - tar->pos);
+ }
+ return MTAR_ESUCCESS;
+}
+
+
+int mtar_finalize(mtar_t *tar) {
+ /* Write two NULL records */
+ return write_null_bytes(tar, sizeof(mtar_raw_header_t) * 2);
+}
\ No newline at end of file
--- /dev/null
+/**
+ * Copyright (c) 2017 rxi
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MIT license. See `microtar.c` for details.
+ */
+
+#ifndef MICROTAR_H
+#define MICROTAR_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define MTAR_VERSION "0.1.0"
+
+enum {
+ MTAR_ESUCCESS = 0,
+ MTAR_EFAILURE = -1,
+ MTAR_EOPENFAIL = -2,
+ MTAR_EREADFAIL = -3,
+ MTAR_EWRITEFAIL = -4,
+ MTAR_ESEEKFAIL = -5,
+ MTAR_EBADCHKSUM = -6,
+ MTAR_ENULLRECORD = -7,
+ MTAR_ENOTFOUND = -8
+};
+
+enum {
+ MTAR_TREG = '0',
+ MTAR_TLNK = '1',
+ MTAR_TSYM = '2',
+ MTAR_TCHR = '3',
+ MTAR_TBLK = '4',
+ MTAR_TDIR = '5',
+ MTAR_TFIFO = '6'
+};
+
+typedef struct {
+ unsigned mode;
+ unsigned owner;
+ unsigned size;
+ unsigned mtime;
+ unsigned type;
+ char name[100];
+ char linkname[100];
+} mtar_header_t;
+
+
+typedef struct mtar_t mtar_t;
+
+struct mtar_t {
+ int (*read)(mtar_t *tar, void *data, unsigned size);
+ int (*write)(mtar_t *tar, const void *data, unsigned size);
+ int (*seek)(mtar_t *tar, unsigned pos);
+ int (*close)(mtar_t *tar);
+ void *stream;
+ unsigned pos;
+ unsigned remaining_data;
+ unsigned last_header;
+};
+
+
+const char* mtar_strerror(int err);
+
+int mtar_open(mtar_t *tar, const char *filename, const char *mode);
+int mtar_close(mtar_t *tar);
+
+int mtar_seek(mtar_t *tar, unsigned pos);
+int mtar_rewind(mtar_t *tar);
+int mtar_next(mtar_t *tar);
+int mtar_find(mtar_t *tar, const char *name, mtar_header_t *h);
+int mtar_read_header(mtar_t *tar, mtar_header_t *h);
+int mtar_read_data(mtar_t *tar, void *ptr, unsigned size);
+
+int mtar_write_header(mtar_t *tar, const mtar_header_t *h);
+int mtar_write_file_header(mtar_t *tar, const char *name, unsigned size);
+int mtar_write_dir_header(mtar_t *tar, const char *name);
+int mtar_write_data(mtar_t *tar, const void *data, unsigned size);
+int mtar_finalize(mtar_t *tar);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file