/* ======================================= KrKr XP3 文件读取 ======================================= */ CR_API sFMT_PRT* load_krkr_xp3 ( __CR_IO__ iDATIN* datin, __CR_IN__ const sLOADER* param ) { int16u idx; int16u len; int32u attr; int64u tots; int64u tsz1; int64u tsz2; int64u pksz; int64u unsz; leng_t back; sARRAY list; byte_t* info; byte_t* pntr; wide_t* name; sXP3_HDR head; iPAK_XP3* port; sFMT_PRT* rett; sPAK_XP3_FILE temp; /* 必须使用自己私有的读取接口 */ datin = create_file_inX(param); if (datin == NULL) return (NULL); array_initT(&list, sPAK_XP3_FILE); list.free = xp3_free; /* 读取文件头信息 */ if (!(CR_VCALL(datin)->geType(datin, &head, sXP3_HDR))) goto _failure1; if (mem_cmp(head.tag, "XP3\r\n \n\x1A\x8B\x67\x01", 11) != 0) goto _failure1; head.idx_pos = QWORD_LE(head.idx_pos); /* 读取文件索引表 */ if (!CR_VCALL(datin)->seek64(datin, head.idx_pos, SEEK_SET)) goto _failure1; if (!CR_VCALL(datin)->getb_no(datin, head.tag)) goto _failure1; if (head.tag[0]) { /* ZLib 压缩的索引表 */ if (!CR_VCALL(datin)->getq_le(datin, &pksz)) goto _failure1; if (!CR_VCALL(datin)->getq_le(datin, &unsz)) goto _failure1; pntr = (byte_t*)mem_malloc64(pksz); if (pntr == NULL) goto _failure1; back = CR_VCALL(datin)->read(datin, pntr, (leng_t)pksz); if (back != (leng_t)pksz) { mem_free(pntr); goto _failure1; } info = (byte_t*)mem_malloc64(unsz); if (info == NULL) { mem_free(pntr); goto _failure1; } back = uncompr_zlib(info, (leng_t)unsz, pntr, (leng_t)pksz); mem_free(pntr); if (back != (leng_t)unsz) goto _failure2; } else { /* 直接读起索引表 */ if (!CR_VCALL(datin)->getq_le(datin, &unsz)) goto _failure1; info = (byte_t*)mem_malloc64(unsz); if (info == NULL) goto _failure1; back = CR_VCALL(datin)->read(datin, info, (leng_t)unsz); if (back != (leng_t)unsz) goto _failure2; } /* 设置加密类型 (如果有的话) */ if (param->aprm != NULL && *(byte_t*)param->aprm != 0x00) attr = PAK_FILE_ENC; else attr = 0; /* 加载文件信息表 */ for (pntr = info, pksz = 0; pksz < unsz;) { /* "File" 数据块 */ if (mem_cmp(pntr, "File", 4) != 0) break; mem_cpy(&tots, pntr + 4, sizeof(int64u)); tots = QWORD_LE(tots); pntr += 12; pksz += 12; if (tots <= 12 + 22 + 12 + 28 || tots > unsz - pksz) goto _failure2; /* "info" 文件总信息 */ if (mem_cmp(pntr, "info", 4) != 0) goto _failure2; mem_cpy(&tsz1, pntr + 4, sizeof(int64u)); tsz1 = QWORD_LE(tsz1); pntr += 12; pksz += 12; if (tsz1 <= 22 || tsz1 > tots - 12 - 12 - 28) goto _failure2; /* 填充一些文件信息结构成员 */ struct_zero(&temp, sPAK_XP3_FILE); mem_cpy(&temp.protect, pntr + 0, sizeof(int32u)); mem_cpy(&temp.base.size, pntr + 4, sizeof(int64u)); mem_cpy(&temp.base.pack, pntr + 12, sizeof(int64u)); temp.base.skip = sizeof(sPAK_XP3_FILE); temp.base.attr = attr; temp.protect = DWORD_LE(temp.protect); temp.base.size = QWORD_LE(temp.base.size); temp.base.pack = QWORD_LE(temp.base.pack); /* 读取文件名 UTF-16 无\0结尾 */ mem_cpy(&len, pntr + 20, sizeof(int16u)); len = WORD_LE(len); if ((int64u)len > tsz1 - 22) goto _failure2; name = str_allocW(len + 1); if (name == NULL) goto _failure2; for (idx = 0; idx < len; idx++) { mem_cpy(&name[idx], pntr + 22 + ((leng_t)idx) * 2, 2); name[idx] = WORD_LE(name[idx]); } name[idx] = 0x0000; temp.base.name = utf16_to_utf8(name); mem_free(name); if (temp.base.name == NULL) goto _failure2; pntr += (leng_t)tsz1; pksz += (leng_t)tsz1; /* "segm" 文件分段信息 */ if (mem_cmp(pntr, "segm", 4) != 0) goto _failure3; mem_cpy(&tsz2, pntr + 4, sizeof(int64u)); tsz2 = QWORD_LE(tsz2); pntr += 12; pksz += 12; if (tsz2 < 28 || tsz2 % 28 != 0 || tsz2 > tots - 12 - tsz1 - 12) goto _failure3; /* 读取所有分段信息 */ temp.segm_lst = mem_talloc64(tsz2 / 28, sPAK_XP3_SEGM); if (temp.segm_lst == NULL) goto _failure3; temp.segm_cnt = (leng_t)(tsz2 / 28); mem_cpy(temp.segm_lst, pntr, (leng_t)tsz2); for (back = 0; back < temp.segm_cnt; back++) { temp.segm_lst[back].zlib = DWORD_LE(temp.segm_lst[back].zlib); temp.segm_lst[back].offset = QWORD_LE(temp.segm_lst[back].offset); temp.segm_lst[back].unsize = QWORD_LE(temp.segm_lst[back].unsize); temp.segm_lst[back].pksize = QWORD_LE(temp.segm_lst[back].pksize); if (temp.segm_lst[back].unsize > temp.base.size) goto _failure4; if (temp.segm_lst[back].pksize > temp.base.pack) goto _failure4; } pntr += (leng_t)tsz2; pksz += (leng_t)tsz2; /* 其他非重要数据段 */ if (tots > 12 + tsz1 + 12 + tsz2) { tots -= 12 + tsz1 + 12 + tsz2; /* "adlr" 附加数据 */ if (mem_cmp(pntr, "adlr", 4) == 0) { if (tots < 16) goto _failure4; mem_cpy(&temp.adlr_key, pntr + 4, sizeof(int32u)); temp.adlr_key = DWORD_LE(temp.adlr_key); } pntr += (leng_t)tots; pksz += (leng_t)tots; } /* 用第一段设置剩下的成员 */ temp.base.offs = temp.segm_lst[0].offset; if (temp.segm_lst[0].zlib) { if (attr == 0) temp.base.memo = "ZLib"; else temp.base.memo = "ZLib + Encrypt"; temp.base.attr |= PAK_FILE_CMP; } else { if (attr == 0) temp.base.memo = "Store"; else temp.base.memo = "Encrypt"; } /* 文件信息压入列表 */ if (array_push_growT(&list, sPAK_XP3_FILE, &temp) == NULL) goto _failure4; } mem_free(info); /* 固定一下列表大小 */ if (!array_no_growT(&list, sPAK_XP3_FILE)) goto _failure1; /* 生成读包接口对象 */ port = struct_new(iPAK_XP3); if (port == NULL) goto _failure1; port->m_file = datin; port->m_cnt = array_get_sizeT(&list, sPAK_XP3_FILE); port->pack.__filelst__ = array_get_dataT(&list, sPAK_FILE); port->pack.__vptr__ = &s_pack_vtbl; if (!pack_init_list((iPACKAGE*)port, TRUE)) { mem_free(port); goto _failure1; } /* 设置解密回调 (传入名称字符串) */ if (attr != 0) { decode_setup(port, (ansi_t*)param->aprm); } else { port->decode_file = NULL; port->decode_block = NULL; } /* 返回读取的文件数据 */ rett = struct_new(sFMT_PRT); if (rett == NULL) { iPAK_XP3_release((iPACKAGE*)port); return (NULL); } rett->type = CR_FMTZ_PRT; rett->port = (iPORT*)port; rett->more = "iPACKAGE"; rett->infor = "KiriKiri2 XP3 Archive (XP3)"; return (rett); _failure4: mem_free(temp.segm_lst); _failure3: mem_free(temp.base.name); _failure2: mem_free(info); _failure1: array_freeT(&list, sPAK_XP3_FILE); CR_VCALL(datin)->release(datin); return (NULL); }
int main(void) { halInit(); /* Kernel initialization, the main() function becomes a thread with * priority NORMALPRIO and the RTOS is active. */ chSysInit(); /* Piksi hardware initialization. */ init(); settings_setup(); signal_init(); check_nap_auth(); static char nap_version_string[64] = {0}; nap_conf_rd_version_string(nap_version_string); log_info("NAP firmware version: %s", nap_version_string); /* Check we are running a compatible version of the NAP firmware. */ const char *required_nap_version = "v0.16"; if (compare_version(nap_version_string, required_nap_version) < 0) { while (1) { log_error("NAP firmware version >= %s required, please update!" "(instructions can be found at http://docs.swift-nav.com/)", required_nap_version); chThdSleepSeconds(2); } } static s32 serial_number; serial_number = nap_conf_rd_serial_number(); frontend_setup(); timing_setup(); ext_event_setup(); position_setup(); track_setup(); track_gps_l1ca_register(); decode_setup(); decode_gps_l1_register(); manage_acq_setup(); manage_track_setup(); system_monitor_setup(); base_obs_setup(); solution_setup(); simulator_setup(); sbp_fileio_setup(); ext_setup(); pps_setup(); READ_ONLY_PARAMETER("system_info", "serial_number", serial_number, TYPE_INT); READ_ONLY_PARAMETER("system_info", "firmware_version", GIT_VERSION, TYPE_STRING); READ_ONLY_PARAMETER("system_info", "firmware_built", __DATE__ " " __TIME__, TYPE_STRING); static struct setting hw_rev = { "system_info", "hw_revision", NULL, 0, settings_read_only_notify, NULL, NULL, false }; hw_rev.addr = (char *)nap_conf_rd_hw_rev_string(); hw_rev.len = strlen(hw_rev.addr); settings_register(&hw_rev, TYPE_STRING); READ_ONLY_PARAMETER("system_info", "nap_version", nap_version_string, TYPE_STRING); READ_ONLY_PARAMETER("system_info", "nap_channels", nap_track_n_channels, TYPE_INT); READ_ONLY_PARAMETER("system_info", "nap_fft_index_bits", nap_acq_fft_index_bits, TYPE_INT); ephemeris_setup(); /* Send message to inform host we are up and running. */ u32 startup_flags = 0; sbp_send_msg(SBP_MSG_STARTUP, sizeof(startup_flags), (u8 *)&startup_flags); while (1) { chThdSleepSeconds(60); } }