A59 -V1.1版本提交
21
.vscode/settings.json
vendored
@ -2,6 +2,23 @@
|
||||
"files.associations": {
|
||||
"*.inc": "c",
|
||||
"navigator.h": "c",
|
||||
"main_loop_simple.h": "c"
|
||||
}
|
||||
"main_loop_simple.h": "c",
|
||||
"pwm.h": "c",
|
||||
"sfud.h": "c",
|
||||
"can_protocol.h": "c",
|
||||
"awtk.h": "c",
|
||||
"types_def.h": "c",
|
||||
"gpio_protocol.h": "c",
|
||||
"data_port.h": "c",
|
||||
"serial.h": "c",
|
||||
"ff_stdio.h": "c",
|
||||
"ff_sfdisk.h": "c",
|
||||
"universal.h": "c",
|
||||
"data_communication_send.h": "c",
|
||||
"object_date_time.h": "c",
|
||||
"semphr.h": "c",
|
||||
"user_data.h": "c",
|
||||
"qr.h": "c"
|
||||
},
|
||||
"cmake.sourceDirectory": "G:/MXC_A58/lib/awtk/awtk/3rd/mbedtls/include"
|
||||
}
|
@ -263,8 +263,8 @@
|
||||
|
||||
#ifdef WIFI_SUPPORT
|
||||
#define CARLINK_EY 0
|
||||
#define CARLINK_EC 0
|
||||
#define CARLINK_CP 1
|
||||
#define CARLINK_EC 1
|
||||
#define CARLINK_CP 0
|
||||
#define CARLINK_AA 0
|
||||
|
||||
#define WIFI_RESET_IO 12
|
||||
@ -287,7 +287,7 @@
|
||||
#error "Do not choose two car links"
|
||||
#elif (CARLINK_EC && CARLINK_AA)
|
||||
#error "Do not choose two car links"
|
||||
#elif (CARLINK_CP && CARLINK_AA)
|
||||
// #elif (CARLINK_CP && CARLINK_AA)
|
||||
#error "Do not choose two car links"
|
||||
#endif
|
||||
|
||||
@ -411,7 +411,7 @@
|
||||
#define UPDATEFILE_MAX_SIZE 0xb00000
|
||||
#define OTA_MEDIA_OFFSET 0xa00000
|
||||
#define OTA_MEDIA_SIZE 0x500000
|
||||
//#define SPI0_QSPI_MODE
|
||||
// #define SPI0_QSPI_MODE
|
||||
#elif DEVICE_TYPE_SELECT == EMMC_FLASH
|
||||
#define LOADER_OFFSET 0x0
|
||||
#define LOADERB_OFFSET 0x100000
|
||||
@ -474,7 +474,7 @@
|
||||
/*********************************************/
|
||||
|
||||
/********** update address configuration **********/
|
||||
//#define OTA_UPDATE_SUPPORT
|
||||
#define OTA_UPDATE_SUPPORT
|
||||
#ifdef OTA_UPDATE_SUPPORT
|
||||
//#define WIFI_UPDATE_SUPPORT
|
||||
#if defined(WIFI_UPDATE_SUPPORT) && !defined(USB_SUPPORT)
|
||||
|
@ -19,7 +19,9 @@ typedef struct {
|
||||
unsigned int image_offset;
|
||||
unsigned int loader_offset;
|
||||
unsigned int loader_size;
|
||||
unsigned int reserved[12];
|
||||
unsigned int reserved[10];
|
||||
unsigned int upgrade_flag;
|
||||
unsigned int upgrade_appsize;
|
||||
unsigned int checksum;
|
||||
} SysInfo;
|
||||
|
||||
|
656
ArkmicroFiles/libboard-amt630hv100/source/animation - 0912.c
Normal file
@ -0,0 +1,656 @@
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
#include "board.h"
|
||||
#include "chip.h"
|
||||
|
||||
#include "sfud.h"
|
||||
#include "updatefile.h"
|
||||
#include "mfcapi.h"
|
||||
#include "dwl.h"
|
||||
#include "animation.h"
|
||||
|
||||
#if DEVICE_TYPE_SELECT == EMMC_FLASH
|
||||
#include "mmcsd_core.h"
|
||||
#endif
|
||||
|
||||
static TaskHandle_t animation_task = NULL;
|
||||
static SemaphoreHandle_t animation_mutex;
|
||||
#if ANIMATION_POLICY == ANIMATION_USE_SMALL_MEM
|
||||
static BANIHEADER ani_header;
|
||||
static BANIHEADER *aniheader = &ani_header;
|
||||
#else
|
||||
static BANIHEADER *aniheader;
|
||||
#endif
|
||||
static unsigned int anioffset;
|
||||
static unsigned int anisize;
|
||||
static int ani_playing = 0;
|
||||
static int ani_replay = 0;
|
||||
static int ani_stop = 0;
|
||||
static int ani_frames = 0;
|
||||
static int ani_display_index = 0;
|
||||
static int ani_take_vdisbuf = 0;
|
||||
static unsigned int ani_frame_addr;
|
||||
static uint32_t first_show_done = 0;
|
||||
|
||||
|
||||
#if 0
|
||||
#include "ff_stdio.h"
|
||||
|
||||
static int get_h264_single_file_from_sd(void *buf, int *len)
|
||||
{
|
||||
#define READ_SIZE (LCD_WIDTH*LCD_HEIGHT*2)
|
||||
char path_name[64] = "/sd/000.h264";
|
||||
static int count = 0;
|
||||
FF_FILE *fp;
|
||||
int ret = -1;
|
||||
|
||||
sprintf(path_name, "/sd/%.3d.h264", count++);
|
||||
*len = 0;
|
||||
|
||||
fp = ff_fopen(path_name, "rb");
|
||||
if (fp) {
|
||||
ret = ff_fread(buf, 1, READ_SIZE, fp);
|
||||
if (ret <= 0) {
|
||||
printf("read sdmmc file:%s failed, maybe read done\n", path_name);
|
||||
return -1;
|
||||
}
|
||||
*len = ret;
|
||||
} else {
|
||||
printf("### open %s fail.\n", path_name);
|
||||
count = 0;
|
||||
return -1;
|
||||
}
|
||||
if(fp)
|
||||
ff_fclose(fp);
|
||||
|
||||
//printf("###read %s len:%d.\n", path_name, *len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void h264_decode_test_thread(void *param)
|
||||
{
|
||||
#define H264DEC_SEMIPLANAR_YUV420 0x020001
|
||||
#define H264DEC_INBUF_SIZE (LCD_WIDTH*LCD_HEIGHT*2)
|
||||
#define H264DEC_DISP_COUNTS 2
|
||||
|
||||
DWLLinearMem_t inBuf;
|
||||
OutFrameBuffer outBuf = {0};
|
||||
uint32_t h264SrcSize = 0;
|
||||
MFCHandle *handle = NULL;
|
||||
uint32_t display_addr[H264DEC_DISP_COUNTS] = {0};
|
||||
uint32_t display_addr_index = 0;
|
||||
uint32_t first_show_done = 0;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
void *h264SrcBuf = pvPortMalloc(H264DEC_INBUF_SIZE);
|
||||
if(!h264SrcBuf) {
|
||||
printf("%s, h264SrcBuf pvPortMalloc failed.\n", __func__);
|
||||
return ;
|
||||
}
|
||||
|
||||
for(i=0; i<H264DEC_DISP_COUNTS; i++) {
|
||||
display_addr[i] = (uint32_t)pvPortMalloc(H264DEC_INBUF_SIZE);
|
||||
if(!display_addr[i] ) {
|
||||
printf("%s, display_addr[%d] pvPortMalloc failed.\n", __func__, i);
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
mmcsd_wait_cd_changed(portMAX_DELAY);
|
||||
|
||||
handle = mfc_init(RAW_STRM_TYPE_H264);
|
||||
if(!handle) {
|
||||
printf("%s, mfc_init failed.\n", __func__);
|
||||
return ;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
//memset(&outBuf, 0, sizeof(OutFrameBuffer));
|
||||
//memset(h264SrcBuf, 0, H264DEC_INBUF_SIZE);
|
||||
mdelay(30);
|
||||
#if 1 //get h264 info form sdcard.
|
||||
ret = get_h264_single_file_from_sd(h264SrcBuf, &h264SrcSize);
|
||||
if(ret != 0) {
|
||||
printf("%s, get_h264_single_file_from_sd failed.\n", __func__);
|
||||
continue;
|
||||
}
|
||||
inBuf.busAddress = (u32)h264SrcBuf;
|
||||
inBuf.virtualAddress = (u32 *)inBuf.busAddress;
|
||||
inBuf.size = h264SrcSize;
|
||||
CP15_clean_dcache_for_dma(inBuf.busAddress, inBuf.busAddress + inBuf.size);
|
||||
#else
|
||||
//1. copy your h264 data to h264SrcBuf;
|
||||
//2. set your h264 data size to h264SrcSize;
|
||||
|
||||
inBuf.busAddress = (u32)h264SrcBuf;
|
||||
inBuf.virtualAddress = (u32 *)inBuf.busAddress;
|
||||
inBuf.size = h264SrcSize;
|
||||
#endif
|
||||
|
||||
ret = mfc_decode(handle, &inBuf, &outBuf);
|
||||
if (ret < 0) {
|
||||
printf("animation decode fail.\n");
|
||||
} else {
|
||||
uint32_t align_width, align_height;
|
||||
uint32_t yaddr, uaddr, vaddr;
|
||||
|
||||
for(i=0; i<outBuf.num; i++) {
|
||||
align_width = outBuf.frameWidth;
|
||||
align_height = outBuf.frameHeight;
|
||||
if(1/*outBuf.outputFormat == H264DEC_SEMIPLANAR_YUV420*/ && align_width && align_height)
|
||||
{
|
||||
memcpy((void *)display_addr[display_addr_index], outBuf.buffer[i].pyVirAddress, align_width * align_height * 3 / 2);
|
||||
// ret = dma_m2mcpy(display_addr[display_addr_index], (uint32_t)outBuf.buffer[i].yBusAddress, align_width * align_height * 3 / 2);
|
||||
// if(ret) {
|
||||
// printf("%s() dma_m2m_memcpy failed.\n", __func__);
|
||||
// continue;
|
||||
// }
|
||||
yaddr = display_addr[display_addr_index];
|
||||
uaddr = yaddr + align_width * align_height;
|
||||
vaddr = yaddr + align_width * align_height * 5/4;
|
||||
|
||||
display_addr_index++;
|
||||
if(display_addr_index >= H264DEC_DISP_COUNTS) {
|
||||
display_addr_index = 0;
|
||||
}
|
||||
|
||||
if(!first_show_done) {
|
||||
ark_lcd_set_osd_size(LCD_VIDEO_LAYER, /*outBuf.codedWidth, outBuf.codedHeight*/LCD_WIDTH, LCD_HEIGHT);
|
||||
ark_lcd_set_osd_format(LCD_VIDEO_LAYER, LCD_OSD_FORAMT_YUV420);
|
||||
ark_lcd_set_osd_yuv420_mode(LCD_VIDEO_LAYER, LCD_OSD_Y_UV420);
|
||||
ark_lcd_osd_enable(LCD_VIDEO_LAYER, 1);
|
||||
ark_lcd_osd_enable(LCD_UI_LAYER, 0);
|
||||
first_show_done = 1;
|
||||
}
|
||||
ark_lcd_set_osd_yaddr(LCD_VIDEO_LAYER, yaddr);
|
||||
ark_lcd_set_osd_uaddr(LCD_VIDEO_LAYER, uaddr);
|
||||
ark_lcd_set_osd_vaddr(LCD_VIDEO_LAYER, vaddr);
|
||||
ark_lcd_set_osd_sync(LCD_VIDEO_LAYER);
|
||||
ark_lcd_set_osd_sync(LCD_UI_LAYER);
|
||||
ark_lcd_wait_for_vsync();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(handle)
|
||||
mfc_uninit(handle);
|
||||
|
||||
if(h264SrcBuf)
|
||||
vPortFree(h264SrcBuf);
|
||||
|
||||
for(i=0; i<H264DEC_DISP_COUNTS; i++) {
|
||||
if(!display_addr[i]) {
|
||||
vPortFree((void *)display_addr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int save_nv12_file_to_sd(void *buf, int len)
|
||||
{
|
||||
char path_name[64] = "/sd/000.bin";
|
||||
static int count = 0;
|
||||
FF_FILE *fp;
|
||||
int ret = -1;
|
||||
|
||||
sprintf(path_name, "/sd/%.3d.bin", count++);
|
||||
|
||||
fp = ff_fopen(path_name, "w+");
|
||||
if (fp) {
|
||||
ret = ff_fwrite(buf, 1, len, fp);
|
||||
if (ret != len) {
|
||||
printf("read sdmmc file:%s failed.\n", path_name);
|
||||
ff_fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
printf("### open %s fail.\n", path_name);
|
||||
return -1;
|
||||
}
|
||||
ff_fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_file_from_sd(void *buf, int *len)
|
||||
{
|
||||
#define READ_SIZE (LCD_WIDTH*LCD_HEIGHT*2)
|
||||
#if LCD_BPP == 32
|
||||
char path_name[64] = "/sd/480x1280_rgb888.rgb";
|
||||
#else
|
||||
char path_name[64] = "/sd/480x1280_rgb565.rgb";
|
||||
#endif
|
||||
FF_FILE *fp;
|
||||
int ret = -1;
|
||||
|
||||
*len = 0;
|
||||
fp = ff_fopen(path_name, "rb");
|
||||
if (fp) {
|
||||
ret = ff_fread(buf, 1, READ_SIZE, fp);
|
||||
if (ret <= 0) {
|
||||
printf("read sdmmc file:%s failed.\n", path_name);
|
||||
return -1;
|
||||
}
|
||||
*len = ret;
|
||||
} else {
|
||||
printf("### open %s fail.\n", path_name);
|
||||
return -1;
|
||||
}
|
||||
if(fp)
|
||||
ff_fclose(fp);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mipi_disp_test(void)
|
||||
{
|
||||
u32 len;
|
||||
int ret;
|
||||
u32 *disp_addr = (u32 *)pvPortMalloc(LCD_WIDTH*LCD_HEIGHT*2);
|
||||
if(!disp_addr) {
|
||||
printf("disp_addr pvPortMalloc failed.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
mmcsd_wait_cd_changed(portMAX_DELAY);
|
||||
get_file_from_sd(disp_addr, &len);
|
||||
if(!len) {
|
||||
printf("get_file_from_sd failed.\n");
|
||||
return ;
|
||||
}
|
||||
CP15_clean_dcache_for_dma((uint32_t)disp_addr, (uint32_t)disp_addr + LCD_WIDTH*LCD_HEIGHT*2);
|
||||
|
||||
u32 layer = LCD_OSD0;
|
||||
u32 width = VIDEO_DISPLAY_WIDTH;
|
||||
u32 height = VIDEO_DISPLAY_HEIGHT;
|
||||
u32 format;
|
||||
#if LCD_BPP == 32
|
||||
format = LCD_OSD_FORAMT_ARGB888;
|
||||
#else
|
||||
format = LCD_OSD_FORAMT_RGB565;
|
||||
#endif
|
||||
|
||||
while(1) {
|
||||
ark_lcd_osd_enable(LCD_OSD0, 0);
|
||||
ark_lcd_osd_enable(LCD_OSD1, 0);
|
||||
ark_lcd_set_osd_sync(LCD_OSD0);
|
||||
ark_lcd_set_osd_sync(LCD_OSD1);
|
||||
|
||||
ark_lcd_set_osd_size(layer, width, height);
|
||||
ark_lcd_set_osd_format(layer, format);
|
||||
ark_lcd_osd_enable(layer, 1);
|
||||
ark_lcd_set_osd_yaddr(layer, (u32)disp_addr);
|
||||
ark_lcd_set_osd_sync(layer);
|
||||
ark_lcd_wait_for_vsync();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//#define PLAY_SHUTDOWN_ANIMATION
|
||||
#ifdef PLAY_SHUTDOWN_ANIMATION
|
||||
static int shutdown_anim = 0;
|
||||
#endif
|
||||
uint16_t animo_flag = 0;
|
||||
static void animation_thread(void *param)
|
||||
{
|
||||
MFCHandle *mfc_handle = NULL;
|
||||
#if DEVICE_TYPE_SELECT != EMMC_FLASH
|
||||
sfud_flash *sflash;
|
||||
#endif
|
||||
uint32_t size;
|
||||
uint32_t stick, etick, delaytick;
|
||||
uint32_t display_addr;
|
||||
uint32_t *tmp_addr = NULL;
|
||||
uint8_t power=1;
|
||||
|
||||
anioffset = GetUpFileOffset(MKTAG('B', 'A', 'N', 'I'));
|
||||
anisize = GetUpFileSize(MKTAG('B', 'A', 'N', 'I'));
|
||||
|
||||
#ifdef PLAY_SHUTDOWN_ANIMATION
|
||||
if(shutdown_anim){
|
||||
anioffset = GetUpFileOffset(MKTAG('S', 'A', 'N', 'I'));
|
||||
anisize = GetUpFileSize(MKTAG('S', 'A', 'N', 'I'));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (anisize > 0) {
|
||||
void *anibuf = pvPortMalloc(anisize);
|
||||
if (anibuf) {
|
||||
#if DEVICE_TYPE_SELECT != EMMC_FLASH
|
||||
sflash = sfud_get_device(0);
|
||||
sfud_read(sflash, anioffset, anisize, anibuf);
|
||||
#else
|
||||
emmc_read(anioffset, anisize, anibuf);
|
||||
#endif
|
||||
aniheader = (BANIHEADER*)anibuf;
|
||||
|
||||
if (aniheader->magic != MKTAG('B', 'A', 'N', 'I')
|
||||
#ifdef PLAY_SHUTDOWN_ANIMATION
|
||||
&& aniheader->magic != MKTAG('S', 'A', 'N', 'I')
|
||||
#endif
|
||||
) {
|
||||
printf("Read animation file error!\n");
|
||||
vPortFree(anibuf);
|
||||
vTaskDelete(NULL);
|
||||
return;
|
||||
}
|
||||
CP15_clean_dcache_for_dma((uint32_t)anibuf, (uint32_t)anibuf + anisize);
|
||||
} else {
|
||||
printf("Error! No enough memory for animation file.\n");
|
||||
vTaskDelete(NULL);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
printf("Warning! Not found animation in update file.\n");
|
||||
vTaskDelete(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
ani_frame_addr = (uint32_t)aniheader + sizeof(BANIHEADER);
|
||||
for (;;) {
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
xSemaphoreTake(animation_mutex, portMAX_DELAY);
|
||||
if (ani_replay) {
|
||||
ani_frame_addr = (uint32_t)aniheader + sizeof(BANIHEADER);
|
||||
ani_frames = 0;
|
||||
ani_replay = 0;
|
||||
}
|
||||
stick = xTaskGetTickCount();
|
||||
ani_playing = 1;
|
||||
|
||||
size = *(uint32_t*)ani_frame_addr;
|
||||
|
||||
if (xVideoDisplayBufTake(pdMS_TO_TICKS(10)) == pdTRUE) {
|
||||
if(!mfc_handle)
|
||||
mfc_handle = mfc_init(RAW_STRM_TYPE_JPEG);
|
||||
if(!mfc_handle) {
|
||||
printf("%s, mfc_init failed.\n", __func__);
|
||||
continue ;
|
||||
}
|
||||
|
||||
display_addr = ulVideoDisplayBufGet();
|
||||
|
||||
JpegHeaderInfo jpegInfo = {0};
|
||||
jpegInfo.handle = mfc_handle;
|
||||
jpegInfo.jpg_addr = ani_frame_addr + 8;
|
||||
jpegInfo.jpg_size = size;
|
||||
jpegInfo.dec_addry = display_addr;
|
||||
|
||||
#if LCD_ROTATE_ANGLE != LCD_ROTATE_ANGLE_0
|
||||
if(!tmp_addr) {
|
||||
uint32_t tmp_size = ulVideoDisplayBufGetSize();
|
||||
tmp_addr = (u32 *)pvPortMalloc(tmp_size);
|
||||
if(!tmp_addr) {
|
||||
printf("tmp_addr pvPortMalloc failed.\n");
|
||||
}
|
||||
}
|
||||
if(tmp_addr) {
|
||||
jpegInfo.dec_addry = VIRT_TO_PHY((u32)tmp_addr);
|
||||
}
|
||||
#endif
|
||||
if (mfc_jpegdec(&jpegInfo) != 0) {
|
||||
printf("animation decode %d frame fail.\n", ani_frames);
|
||||
vVideoDisplayBufFree(display_addr);
|
||||
} else {
|
||||
if(!first_show_done) {
|
||||
#if LCD_ROTATE_ANGLE == LCD_ROTATE_ANGLE_0
|
||||
int align_width = (LCD_WIDTH + 0xF) & (~0xF);
|
||||
int align_height = (LCD_HEIGHT + 0xF) & (~0xF);
|
||||
if((align_width == jpegInfo.dec_width) && (align_height == jpegInfo.dec_height)) {
|
||||
ark_lcd_set_osd_size(LCD_VIDEO_LAYER, LCD_WIDTH, LCD_HEIGHT);
|
||||
} else {
|
||||
ark_lcd_set_osd_size(LCD_VIDEO_LAYER, jpegInfo.dec_width, jpegInfo.dec_height);
|
||||
}
|
||||
ark_lcd_set_osd_format(LCD_VIDEO_LAYER, LCD_OSD_FORAMT_YUV420);
|
||||
ark_lcd_set_osd_yuv420_mode(LCD_VIDEO_LAYER, LCD_OSD_Y_UV420);
|
||||
#else
|
||||
ark_lcd_set_osd_size(LCD_VIDEO_LAYER, LCD_WIDTH, LCD_HEIGHT);
|
||||
ark_lcd_set_osd_format(LCD_VIDEO_LAYER, LCD_OSD_FORAMT_RGB565);
|
||||
#endif
|
||||
|
||||
ark_lcd_osd_enable(LCD_VIDEO_LAYER, 1);
|
||||
ark_lcd_osd_enable(LCD_UI_LAYER, 0);
|
||||
first_show_done = 1;
|
||||
}
|
||||
animo_flag++;
|
||||
if(animo_flag == 3){
|
||||
BrightnessPowerOnSetting();
|
||||
pwm_enable(2);
|
||||
pwm_enable(3);
|
||||
}
|
||||
// printf("animo_flag------------ %d .\r\n",animo_flag);
|
||||
#if LCD_ROTATE_ANGLE == LCD_ROTATE_ANGLE_0
|
||||
ark_lcd_set_osd_yaddr(LCD_VIDEO_LAYER, jpegInfo.dec_addry);
|
||||
ark_lcd_set_osd_uaddr(LCD_VIDEO_LAYER, jpegInfo.dec_addru);
|
||||
ark_lcd_set_osd_vaddr(LCD_VIDEO_LAYER, jpegInfo.dec_addrv);
|
||||
#else
|
||||
pxp_scaler_rotate(jpegInfo.dec_addry, jpegInfo.dec_addru, jpegInfo.dec_addrv,
|
||||
PXP_SRC_FMT_YUV2P420, jpegInfo.dec_width, jpegInfo.dec_height,
|
||||
display_addr, 0, PXP_OUT_FMT_RGB565, LCD_WIDTH, LCD_HEIGHT, LCD_ROTATE_ANGLE);
|
||||
ark_lcd_set_osd_yaddr(LCD_VIDEO_LAYER, display_addr);
|
||||
#endif
|
||||
ark_lcd_set_osd_sync(LCD_VIDEO_LAYER);
|
||||
ark_lcd_set_osd_sync(LCD_UI_LAYER);
|
||||
ark_lcd_wait_for_vsync();
|
||||
vVideoDisplayBufRender(display_addr);
|
||||
ani_take_vdisbuf = 1;
|
||||
}
|
||||
}
|
||||
|
||||
ani_frame_addr += size;
|
||||
ani_display_index = !ani_display_index;
|
||||
|
||||
if (ani_stop || (++ani_frames >= aniheader->aniCount + aniheader->hasBootlogo ? 1 : 0)
|
||||
#if ANIMATION_POLICY == ANIMATION_USE_SMALL_MEM
|
||||
|| (ani_frame_addr > anioffset + anisize))
|
||||
#else
|
||||
|| (ani_frame_addr > (uint32_t)aniheader + anisize))
|
||||
#endif
|
||||
{
|
||||
|
||||
printf("animation end.\n");
|
||||
extern void Set_sys_power_on_self_test(uint8_t value);
|
||||
Set_sys_power_on_self_test(50);
|
||||
ani_stop = 0;
|
||||
if (aniheader->aniCount > 0)
|
||||
vTaskDelay(aniheader->aniDelayHideTime);
|
||||
else if (aniheader->hasBootlogo)
|
||||
vTaskDelay(aniheader->bootlogoDisplayTime);
|
||||
|
||||
#ifdef PLAY_SHUTDOWN_ANIMATION
|
||||
if(shutdown_anim)
|
||||
ani_take_vdisbuf = 0;
|
||||
#endif
|
||||
if (ani_take_vdisbuf) {
|
||||
ark_lcd_osd_enable(LCD_VIDEO_LAYER, 0);
|
||||
ark_lcd_osd_enable(LCD_UI_LAYER, 1);
|
||||
ark_lcd_set_osd_sync(LCD_UI_LAYER);
|
||||
ark_lcd_set_osd_sync(LCD_VIDEO_LAYER);
|
||||
}
|
||||
vVideoDisplayBufFree(display_addr);
|
||||
vVideoDisplayBufGive();
|
||||
ani_playing = 0;
|
||||
if (ani_replay)
|
||||
xTaskNotifyGive(animation_task);
|
||||
xSemaphoreGive(animation_mutex);
|
||||
|
||||
if(mfc_handle) {
|
||||
mfc_uninit(mfc_handle);
|
||||
mfc_handle = NULL;
|
||||
}
|
||||
if(tmp_addr) {
|
||||
vPortFree(tmp_addr);
|
||||
tmp_addr = NULL;
|
||||
}
|
||||
|
||||
#ifdef PLAY_SHUTDOWN_ANIMATION
|
||||
break;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
vVideoDisplayBufGive();
|
||||
xSemaphoreGive(animation_mutex);
|
||||
etick = xTaskGetTickCount();
|
||||
|
||||
if (aniheader->hasBootlogo && ani_frames == 1)
|
||||
delaytick = pdMS_TO_TICKS(aniheader->bootlogoDisplayTime) > (etick - stick) ?
|
||||
pdMS_TO_TICKS(aniheader->bootlogoDisplayTime) - (etick - stick) : 0;
|
||||
else
|
||||
delaytick = pdMS_TO_TICKS(1000 / aniheader->aniFps) > (etick - stick) ?
|
||||
pdMS_TO_TICKS(1000 / aniheader->aniFps) - (etick - stick) : 0;
|
||||
|
||||
if (delaytick)
|
||||
vTaskDelay(delaytick);
|
||||
|
||||
xTaskNotifyGive(animation_task);
|
||||
}
|
||||
|
||||
#ifdef PLAY_SHUTDOWN_ANIMATION
|
||||
if(aniheader) {
|
||||
vPortFree(aniheader);
|
||||
aniheader = NULL;
|
||||
}
|
||||
|
||||
animation_task = NULL;
|
||||
vTaskDelete(NULL);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int animation_init(void)
|
||||
{
|
||||
if (animation_task) {
|
||||
printf("animation is already inited.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
animation_mutex = xSemaphoreCreateMutex();
|
||||
|
||||
/* Create a task to play animation */
|
||||
//if (xTaskCreate(h264_decode_test_thread, "h264_decode_test", configMINIMAL_STACK_SIZE*2, NULL,
|
||||
if (xTaskCreate(animation_thread, "animation", configMINIMAL_STACK_SIZE, NULL,
|
||||
configMAX_PRIORITIES - 1, &animation_task) != pdPASS) {
|
||||
printf("create animation task fail.\n");
|
||||
animation_task = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void animation_start(void)
|
||||
{
|
||||
xSemaphoreTake(animation_mutex, portMAX_DELAY);
|
||||
first_show_done=0;
|
||||
if (ani_playing) {
|
||||
printf("animation is already playing.\n");
|
||||
xSemaphoreGive(animation_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
#if ANIMATION_POLICY == ANIMATION_USE_SMALL_MEM
|
||||
ani_frame_addr = anioffset + sizeof(BANIHEADER);
|
||||
#else
|
||||
ani_frame_addr = (uint32_t)aniheader + sizeof(BANIHEADER);
|
||||
#endif
|
||||
ani_frames = 0;
|
||||
if (animation_task)
|
||||
xTaskNotifyGive(animation_task);
|
||||
|
||||
xSemaphoreGive(animation_mutex);
|
||||
}
|
||||
|
||||
/* replay animation even if animation is already playing */
|
||||
void animation_restart(void)
|
||||
{
|
||||
xSemaphoreTake(animation_mutex, portMAX_DELAY);
|
||||
first_show_done=0;
|
||||
ani_stop=0;
|
||||
if (ani_playing) {
|
||||
ani_replay = 1;
|
||||
xSemaphoreGive(animation_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
#if ANIMATION_POLICY == ANIMATION_USE_SMALL_MEM
|
||||
ani_frame_addr = anioffset + sizeof(BANIHEADER);
|
||||
#else
|
||||
ani_frame_addr = (uint32_t)aniheader + sizeof(BANIHEADER);
|
||||
#endif
|
||||
ani_frames = 0;
|
||||
if (animation_task)
|
||||
xTaskNotifyGive(animation_task);
|
||||
|
||||
xSemaphoreGive(animation_mutex);
|
||||
}
|
||||
|
||||
#ifdef PLAY_SHUTDOWN_ANIMATION
|
||||
int play_shutdown_animation(void)
|
||||
{
|
||||
#define TIMEOUT_SEC 10
|
||||
uint32_t wait_tick;
|
||||
|
||||
if (animation_task) {
|
||||
printf("%s, animation is already inited.\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
xSemaphoreTake(animation_mutex, portMAX_DELAY);
|
||||
shutdown_anim = 1;
|
||||
ani_frames = 0;
|
||||
first_show_done = 0;
|
||||
ani_stop = 0;
|
||||
ani_take_vdisbuf = 0;
|
||||
xSemaphoreGive(animation_mutex);
|
||||
|
||||
if (xTaskCreate(animation_thread, "animation", configMINIMAL_STACK_SIZE, NULL,
|
||||
configMAX_PRIORITIES - 2, &animation_task) != pdPASS) {
|
||||
printf("%s, create animation task fail.\n", __func__);
|
||||
animation_task = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
xSemaphoreTake(animation_mutex, portMAX_DELAY);
|
||||
|
||||
if (ani_playing) {
|
||||
printf("%s, animation is already playing.\n", __func__);
|
||||
xSemaphoreGive(animation_mutex);
|
||||
return -1;
|
||||
}
|
||||
if (animation_task)
|
||||
xTaskNotifyGive(animation_task);
|
||||
xSemaphoreGive(animation_mutex);
|
||||
|
||||
//wait for animation_thread exit.
|
||||
wait_tick = xTaskGetTickCount();
|
||||
while(xTaskGetTickCount() - wait_tick < configTICK_RATE_HZ * TIMEOUT_SEC) {
|
||||
if(ani_stop)
|
||||
break;
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void animation_stop(void)
|
||||
{
|
||||
xSemaphoreTake(animation_mutex, portMAX_DELAY);
|
||||
ani_stop = 1;
|
||||
xSemaphoreGive(animation_mutex);
|
||||
}
|
||||
|
||||
int get_animation_status(void)
|
||||
{
|
||||
return ani_playing;
|
||||
}
|
@ -418,8 +418,8 @@ static void animation_thread(void *param)
|
||||
#endif
|
||||
if(power){
|
||||
BrightnessPowerOnSetting();
|
||||
pwm_enable(2);//?<3F><>?<3F><>?-??<3F><>?<3F><>?<3F>̨<EFBFBD><CCA8><EFBFBD>???<3F><><EFBFBD><EFBFBD>?a??<3F><>31a
|
||||
pwm_enable(3);//?<3F><>?<3F><>?-??<3F><>?<3F><>?<3F>̨<EFBFBD><CCA8><EFBFBD>???<3F><><EFBFBD><EFBFBD>?a??<3F><>?1a
|
||||
pwm_enable(2);
|
||||
pwm_enable(3);
|
||||
}
|
||||
ark_lcd_osd_enable(LCD_VIDEO_LAYER, 1);
|
||||
ark_lcd_osd_enable(LCD_UI_LAYER, 0);
|
||||
@ -536,7 +536,7 @@ int animation_init(void)
|
||||
/* Create a task to play animation */
|
||||
//if (xTaskCreate(h264_decode_test_thread, "h264_decode_test", configMINIMAL_STACK_SIZE*2, NULL,
|
||||
if (xTaskCreate(animation_thread, "animation", configMINIMAL_STACK_SIZE, NULL,
|
||||
configMAX_PRIORITIES - 2, &animation_task) != pdPASS) {
|
||||
configMAX_PRIORITIES - 1, &animation_task) != pdPASS) {
|
||||
printf("create animation task fail.\n");
|
||||
animation_task = NULL;
|
||||
return -1;
|
||||
|
@ -31,6 +31,7 @@ typedef struct {
|
||||
int width;
|
||||
int height;
|
||||
int format;
|
||||
int stride;
|
||||
unsigned int yaddr;
|
||||
unsigned int uaddr;
|
||||
unsigned int vaddr;
|
||||
|
@ -31,6 +31,9 @@ typedef struct sfuddata_t{
|
||||
char r_mac_address[9]; //物理地址
|
||||
uint32_t maintenance_mileage; //保养里程数max
|
||||
uint32_t mileage_flag; //设置时当前的总里程数
|
||||
uint8_t display_mileage; // 里程显示类型
|
||||
uint8_t tcs_on_off; //tcs类型
|
||||
uint8_t mile_state; //保养里程状态
|
||||
}SfudData_t;
|
||||
|
||||
typedef struct sfudmiledata_t{
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "FreeRTOS.h"
|
||||
#include "chip.h"
|
||||
|
||||
//#define CAN_USE_TX_DEMO
|
||||
#define CAN_USE_TX_DEMO
|
||||
|
||||
#define CAN_RX_BUF_NUM 32
|
||||
#define CAN_TX_BUF_NUM 32
|
||||
@ -690,40 +690,66 @@ static void can_txdemo_thread(void *param)
|
||||
{
|
||||
CanPort_t *cap = param;
|
||||
|
||||
// CanMsg txmsg = {0};
|
||||
// txmsg.IDE = CAN_Id_Standard;
|
||||
// txmsg.DLC = 4;
|
||||
// txmsg.Data[0] = 0x11;
|
||||
// txmsg.Data[1] = 0x22;
|
||||
// txmsg.Data[2] = 0x33;
|
||||
// txmsg.Data[3] = 0x44;
|
||||
CanMsg txmsg = {0};
|
||||
txmsg.StdId = 0x200;
|
||||
txmsg.IDE = CAN_Id_Standard;
|
||||
txmsg.DLC = 4;
|
||||
txmsg.Data[0] = 0x11;
|
||||
txmsg.Data[1] = 0x22;
|
||||
txmsg.Data[2] = 0x33;
|
||||
txmsg.Data[3] = 0x44;
|
||||
txmsg.DLC = 8;
|
||||
txmsg.Data[0] = Get_sys_tcs_on_off()?0x8:0x00;
|
||||
|
||||
//uint32_t last_time = get_timer(0);
|
||||
for (;;) {
|
||||
txmsg.Data[0] = Get_sys_tcs_on_off()?0x8:0x00;
|
||||
iCanWrite(cap, &txmsg, 1, 0);
|
||||
|
||||
//printf("%d us.\n", get_timer(last_time));
|
||||
//last_time = get_timer(0);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t can101_flag = 0;
|
||||
static void can_rxdemo_thread(void *param)
|
||||
{
|
||||
CanPort_t *cap = param;
|
||||
int tlv_data_value[8] = {0};
|
||||
|
||||
for (;;) {
|
||||
CanMsg rxmsg[8] = {0};
|
||||
int revlen;
|
||||
int i, j;
|
||||
|
||||
if ((revlen = iCanRead(cap, rxmsg, 8, pdMS_TO_TICKS(200))) > 0) {
|
||||
printf("can receive %d messages:\n", revlen);
|
||||
if ((revlen = iCanRead(cap, rxmsg, 8, pdMS_TO_TICKS(10))) > 0 && (Get_sys_power_on_self_test() == 100)) {
|
||||
for (i = 0; i < revlen; i++) {
|
||||
for (j = 0; j < rxmsg[i].DLC; j++)
|
||||
printf("%.2x, ", rxmsg[i].Data[j]);
|
||||
printf("\n");
|
||||
for (j = 0; j < rxmsg[i].DLC; j++){
|
||||
tlv_data_value[j] = rxmsg[i].Data[j];
|
||||
}
|
||||
// printf("can>> Id = %03x",rxmsg[i].StdId);
|
||||
switch(rxmsg[i].StdId){
|
||||
case 0x37B:
|
||||
tcsworking_event_handing(tlv_data_value);//TCS
|
||||
break;
|
||||
case 0x12B:
|
||||
tcsswitch_event_handing(tlv_data_value);//tcs开关
|
||||
break;
|
||||
case 0x401:
|
||||
break;
|
||||
case 0x402://ECU故障码
|
||||
break;
|
||||
case 0xA5://ABS故障码
|
||||
abs_dtc_event_handing(tlv_data_value);
|
||||
break;
|
||||
case 0xA3://ABS数据
|
||||
break;
|
||||
case 0x101://发送机数据
|
||||
if(can101_flag != 10)
|
||||
can101_flag = 10;
|
||||
speed_event_handing(tlv_data_value);
|
||||
break;
|
||||
default:break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -739,13 +765,13 @@ int can_demo(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
vCanInit(cap, CAN250kBaud, CAN_MODE_NORMAL);
|
||||
vCanInit(cap, CAN500kBaud, CAN_MODE_NORMAL);
|
||||
#if 1
|
||||
CAN_FilterInitTypeDef canfilter = {0};
|
||||
/* 只接收ID的第0位为1的帧 */
|
||||
canfilter.MODE = 1; /* 单滤波器模式 */
|
||||
canfilter.ID = 0x1;
|
||||
canfilter.IDMASK = 0x7fe;
|
||||
canfilter.ID = 0x37B;
|
||||
canfilter.IDMASK = 0x7ff;
|
||||
vCanSetFilter(cap, &canfilter);
|
||||
#endif
|
||||
|
||||
|
@ -160,6 +160,7 @@ struct dw_spi {
|
||||
void (*transfer_handler)(struct dw_spi *dws);
|
||||
u32 current_freq; /* frequency in hz */
|
||||
u32 current_qspi_freq;
|
||||
int xfer_ret;
|
||||
|
||||
/* DMA info */
|
||||
int dma_inited;
|
||||
@ -404,6 +405,7 @@ static void dma_transfer(struct dw_spi *dws)
|
||||
|
||||
dw_readl(dws, DW_SPI_ICR);
|
||||
int_error_stop(dws, "dma_transfer: fifo overrun/underrun");
|
||||
dws->xfer_ret = 1;
|
||||
xQueueSendFromISR(dws->xfer_done, NULL, 0);
|
||||
|
||||
return;
|
||||
@ -626,6 +628,7 @@ xfer_continue:
|
||||
if (ndf > 0xffff) ndf = 0xffff;
|
||||
|
||||
dws->dma_mapped = 1;
|
||||
dws->xfer_ret = 0;
|
||||
dws->rx = (u8*)message->recv_buf + xfer_len;
|
||||
dws->len = (ndf + 1) * dws->n_bytes;
|
||||
dws->rx_end = (u8*)dws->rx + dws->len;
|
||||
@ -721,11 +724,30 @@ xfer_continue:
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (dws->dma_mapped && dws->rx_dummy_buffer) {
|
||||
if (dws->xfer_ret) {
|
||||
dws->xfer_ret = 0;
|
||||
ret = -1;
|
||||
if (dws->dma_mapped)
|
||||
dma_stop_channel(dws->dma_rx);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (dws->dma_mapped) {
|
||||
/* Invalidate cache after dma read, rx and len must align to cacheline(32bytes) */
|
||||
portDISABLE_INTERRUPTS();
|
||||
if (dws->rx_dummy_buffer)
|
||||
CP15_invalidate_dcache_for_dma((uint32_t)dws->rx_dummy_buffer,
|
||||
(uint32_t)dws->rx_dummy_buffer + dws->len);
|
||||
else
|
||||
CP15_invalidate_dcache_for_dma((uint32_t)dws->rx, (uint32_t)dws->rx + dws->len);
|
||||
portENABLE_INTERRUPTS();
|
||||
|
||||
if (dws->rx_dummy_buffer) {
|
||||
memcpy(dws->rx, dws->rx_dummy_buffer, dws->len);
|
||||
vPortFree(dws->rx_dummy_buffer);
|
||||
dws->rx_dummy_buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
dma_stop_channel(dws->dma_rx);
|
||||
|
||||
@ -764,8 +786,7 @@ int dw_spi_setup(struct spi_slave *slave, struct spi_configuration *configuratio
|
||||
chip->qspi_clk_div = (DIV_ROUND_UP(dws->max_freq, configuration->qspi_max_hz) + 1) & 0xfffe;
|
||||
dws->current_freq = dws->max_freq / chip->clk_div;
|
||||
dws->current_qspi_freq = dws->max_freq / chip->qspi_clk_div;
|
||||
printf("spi max_freq %u, current freq %u, qspi_freq %u.\n", dws->max_freq,
|
||||
dws->current_freq, dws->current_qspi_freq);
|
||||
printf("spi max_freq %u, current freq %u, qspi_freq %u.\n", dws->max_freq, dws->current_freq, dws->current_qspi_freq);
|
||||
|
||||
gpio_direction_output(dws->cs_gpio,
|
||||
!(dws->slave.mode & SPI_CS_HIGH));
|
||||
@ -909,7 +930,7 @@ static int dw_spi_dma_transfer(struct dw_spi *dws, struct spi_message *message)
|
||||
cfg.direction = DMA_DEV_TO_MEM;
|
||||
cfg.src_addr = REGS_SPI0_BASE + DW_SPI_DR;
|
||||
//if (((u32)dws->rx/* | dws->len*/) & (ARCH_DMA_MINALIGN - 1)) {
|
||||
if ((u32)dws->rx & 3) {
|
||||
if ((u32)dws->rx & 31) {
|
||||
dws->rx_dummy_buffer = pvPortMalloc(dws->len);
|
||||
if (!dws->rx_dummy_buffer)
|
||||
return -ENOMEM;
|
||||
|
@ -147,7 +147,7 @@ static xPinGroup_t pin_groups[] = {
|
||||
{.groupid = PGRP_I2C1, .pins_num = 2, .pins = {{50, 1}, {51, 1}}},
|
||||
{.groupid = PGRP_LCD_TTL_CH0, .pins_num = 28,
|
||||
/* de clk vynsc hsync */
|
||||
.pins = {{88, 1}, {89, 1, PAD_DRIVE_2MA}, {90, 1}, {91, 1},
|
||||
.pins = {{88, 1}, {89, 1, PAD_DRIVE_2MA}, {90, 0}, {91, 0},
|
||||
{64, 1}, {65, 1}, {66, 1}, {67, 1}, {68, 1}, {69, 1}, {70, 1}, {71, 1}, /* B0-B7 */
|
||||
{72, 1}, {73, 1}, {74, 1}, {75, 1}, {76, 1}, {77, 1}, {78, 1}, {79, 1}, /* G0-G7 */
|
||||
{80, 1}, {81, 1}, {82, 1}, {83, 1}, {84, 1}, {85, 1}, {86, 1}, {87, 1},}}, /* R0-R7 */
|
||||
@ -317,6 +317,7 @@ void vPinctrlSetup(void)
|
||||
pinctrl_set_group(PGRP_ITU_CH1_INV);
|
||||
pinctrl_set_group(PGRP_CAN0_CH0);
|
||||
|
||||
|
||||
#ifdef AUDIO_REPLAY
|
||||
#if (AUDIO_REPLAY_I2S == I2S_ID1)
|
||||
pinctrl_set_group(PGRP_I2S1_PLAY);
|
||||
|
@ -12,13 +12,13 @@
|
||||
#ifndef WITH_MVVM
|
||||
|
||||
SfudData_t sfud_data_saved ={0};
|
||||
#define SFUD_DATA_FLASH_OFFSET 0xfff000
|
||||
#define SFUD_DATA_FLASH_OFFSET 0x1fff000 //32Mflash
|
||||
SfudMileData_t sfud_mile_data ={0};
|
||||
static uint32_t save_addr = 0;
|
||||
static uint16_t User_data_index = 0;
|
||||
#define SFUD_MILE_DATA_FLASH_OFFSET 0xffe000//0xffe000
|
||||
#define MILE_FLASH_OFFSET 0x1000
|
||||
|
||||
/*
|
||||
void read_mileage(uint32_t trip_data,uint32_t total_data)
|
||||
{
|
||||
uint32_t i;
|
||||
@ -96,7 +96,7 @@ void SaveMileageData(uint32_t trip_data,uint32_t total_data){
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
void Classify_SaveDataToFlash(SfudData_t user_data,uint8_t type){
|
||||
uint8_t buff[sizeof(SfudData_t)];//定义buff用于保存结构体
|
||||
memset(buff,0,sizeof(buff));//将buff内存清零
|
||||
@ -137,20 +137,20 @@ void Classify_SaveDataToFlash(SfudData_t user_data,uint8_t type){
|
||||
void SaveDataToFlash(SfudData_t user_data){
|
||||
uint8_t buff[sizeof(SfudData_t)];//定义buff用于保存结构体
|
||||
memset(buff,0,sizeof(buff));//将buff内存清零
|
||||
printf("**************save flash***********************\r\n");
|
||||
// printf("**************save flash***********************\r\n");
|
||||
// printf("user_data==> %d-%d-%d-%d-%d,%d",user_data.language,user_data.display_unit,user_data.theme
|
||||
// ,user_data.theme_state,user_data.light_value,user_data.bt_on_off);
|
||||
printf("mac:%02X%02X%02X%02X%02X%02X , %02X%02X%02X%02X%02X%02X end\r\n",user_data.f_mac_address[0],user_data.f_mac_address[1],user_data.f_mac_address[2]
|
||||
,user_data.f_mac_address[3],user_data.f_mac_address[4],user_data.f_mac_address[5]
|
||||
,user_data.r_mac_address[0],user_data.r_mac_address[1],user_data.r_mac_address[2]
|
||||
,user_data.r_mac_address[3],user_data.r_mac_address[4],user_data.r_mac_address[5]);
|
||||
// printf("mac:%02X%02X%02X%02X%02X%02X , %02X%02X%02X%02X%02X%02X end\r\n",user_data.f_mac_address[0],user_data.f_mac_address[1],user_data.f_mac_address[2]
|
||||
// ,user_data.f_mac_address[3],user_data.f_mac_address[4],user_data.f_mac_address[5]
|
||||
// ,user_data.r_mac_address[0],user_data.r_mac_address[1],user_data.r_mac_address[2]
|
||||
// ,user_data.r_mac_address[3],user_data.r_mac_address[4],user_data.r_mac_address[5]);
|
||||
// printf("data:%02X %02X%02X , %02X %02X%02X end\r\n"
|
||||
// ,user_data.f_mac_address[6],user_data.f_mac_address[7],user_data.f_mac_address[8]
|
||||
// ,user_data.r_mac_address[6],user_data.r_mac_address[7],user_data.r_mac_address[8]);
|
||||
// printf("*************************************\r\n");
|
||||
// printf("mile data: %02X,%02X end\r\n"
|
||||
// ,user_data.maintenance_mileage,user_data.mileage_flag);
|
||||
printf("*************************************\r\n");
|
||||
// printf("*************************************\r\n");
|
||||
|
||||
if(user_data.light_value==0)
|
||||
user_data.light_value=1;
|
||||
@ -169,6 +169,9 @@ void SaveDataToFlash(SfudData_t user_data){
|
||||
strcpy(((SfudData_t *)buff)->r_mac_address,user_data.r_mac_address);
|
||||
((SfudData_t *)buff)->maintenance_mileage = user_data.maintenance_mileage;
|
||||
((SfudData_t *)buff)->mileage_flag = user_data.mileage_flag;
|
||||
((SfudData_t *)buff)->display_mileage = user_data.display_mileage;
|
||||
((SfudData_t *)buff)->tcs_on_off = user_data.tcs_on_off;
|
||||
((SfudData_t *)buff)->mile_state = user_data.mile_state;
|
||||
|
||||
sfud_flash *sflash = sfud_get_device(0);
|
||||
if (sfud_erase_write(sflash,SFUD_DATA_FLASH_OFFSET,sizeof(buff),buff)!=SFUD_SUCCESS){
|
||||
|
@ -833,7 +833,7 @@ static int uup_rx_data_len = 0;
|
||||
#if DEVICE_TYPE_SELECT != EMMC_FLASH
|
||||
#include "ff_sfdisk.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
typedef enum {
|
||||
UART_FRAME_START,
|
||||
UART_FRAME_FILEINFO,
|
||||
@ -855,8 +855,8 @@ typedef enum {
|
||||
#define UUP_MAX_FILE_SIZE 0x1000000
|
||||
#define UUP_RX_FRAME_NUM 16
|
||||
#define UUP_MAX_LOADER_SIZE STEPLDR_MAX_SIZE//0x10000
|
||||
|
||||
static int uup_status = UUP_STATE_IDLE;
|
||||
*/
|
||||
// static int uup_status = UUP_STATE_IDLE;
|
||||
static int uup_file_type = 0;
|
||||
static int uup_file_size = 0;
|
||||
static int uup_packet_num = 0;
|
||||
@ -877,7 +877,7 @@ static void uup_send_ack(UartPort_t *uap, int type, int ret)
|
||||
|
||||
iUartWrite(uap, buf, 7, pdMS_TO_TICKS(100));
|
||||
}
|
||||
|
||||
#if 0
|
||||
void uup_ota_update(UartPort_t *uap, uint8_t *framebuf, size_t len)
|
||||
{
|
||||
int frametype = framebuf[0];
|
||||
@ -1009,6 +1009,9 @@ void uup_ota_update(UartPort_t *uap, uint8_t *framebuf, size_t len)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
static void uart_tx_demo_thread(void *param)
|
||||
{
|
||||
|
@ -69,25 +69,25 @@ static void protocol_uart_tx_thread(void *param)
|
||||
for (;;)
|
||||
{
|
||||
if(uart_tx_flag){
|
||||
if (uart_time_request[0] != 0 && uart_time_request[0] == 0xAA)
|
||||
if (uart_time_request[0] != 0 && (uart_time_request[0] == 0xAA || uart_time_request[0] == 0x27))
|
||||
{
|
||||
//printf("UART3 tx-->>> ");
|
||||
// printf("UART3 tx-->>> ");
|
||||
for (uint8_t i = 0; i < 9; i++)
|
||||
{
|
||||
//printf("%02x ", uart_time_request[i]);
|
||||
// printf("%02x ", uart_time_request[i]);
|
||||
uarttx[i] = uart_time_request[i];
|
||||
}
|
||||
if(uart_time_request[1]==0x10){
|
||||
for (uint8_t i = 9; i < 19; i++)
|
||||
{
|
||||
//printf("%02x ", uart_time_request[i]);
|
||||
// printf("%02x ", uart_time_request[i]);
|
||||
uarttx[i] = uart_time_request[i];
|
||||
}
|
||||
//printf("\r\n");
|
||||
// printf("\r\n");
|
||||
iUartWrite(uap, uarttx, 19, pdMS_TO_TICKS(100)); // 发送数据
|
||||
uart_time_request[0] = 0;
|
||||
}else{
|
||||
//printf("\r\n");
|
||||
// printf("\r\n");
|
||||
iUartWrite(uap, uarttx, 9, pdMS_TO_TICKS(100)); // 发送数据
|
||||
uart_time_request[0] = 0;
|
||||
}
|
||||
@ -126,7 +126,10 @@ static uint16_t calculate_cumulative_sum(uint8_t *buf)
|
||||
|
||||
return sum;
|
||||
}
|
||||
extern uint8_t uart3_flag;
|
||||
uint8_t device_flag = 0;
|
||||
uint8_t data_analysis_flag = 0;
|
||||
uint8_t data_count_flag = 0;
|
||||
uint8_t uart3_flag = 0;
|
||||
static void protocol_uart_rx_thread(void *param)
|
||||
{
|
||||
UartPort_t *uap = xUartOpen(UART_BT_PORT);
|
||||
@ -139,7 +142,7 @@ static void protocol_uart_rx_thread(void *param)
|
||||
|
||||
int i;
|
||||
uint8_t tlv_data_value[128] = {0};
|
||||
unsigned char ota_request[8] = {0x7e,0x00,0x05,0x02,0x03,0x01,0x00,0x01};
|
||||
// unsigned char ota_request[8] = {0x7e,0x00,0x05,0x02,0x03,0x01,0x00,0x01};
|
||||
uint32_t sum = 0;
|
||||
uint8_t equipment_data = 0;
|
||||
uint8_t mac_data = 0;
|
||||
@ -164,13 +167,9 @@ static void protocol_uart_rx_thread(void *param)
|
||||
for (;;)
|
||||
{
|
||||
len = iUartRead(uap, uartrx, BUFFER_LEN, pdMS_TO_TICKS(10));
|
||||
if(uart3_flag){
|
||||
if(len==0)
|
||||
uart3_flag = 0;
|
||||
else
|
||||
printf("len!=0.\r\n");
|
||||
}else if(Get_sys_power_on_self_test() != 150){
|
||||
|
||||
if(Get_sys_power_on_self_test() != 150 ){
|
||||
if(device_flag)
|
||||
data_count_flag++;
|
||||
for(i=0;i<len;i++){
|
||||
switch (upgrade_state) {
|
||||
case 0:
|
||||
@ -214,26 +213,31 @@ static void protocol_uart_rx_thread(void *param)
|
||||
if (uartrx[i] == 0x0a){
|
||||
sum = calculate_cumulative_sum(tlv_data_value);
|
||||
if(sum != tlv_data_value[str_len-1]){
|
||||
//printf("error.\r\n");
|
||||
printf("error.\r\n");
|
||||
}else{
|
||||
if(equipment_data){
|
||||
device_data_analysis(tlv_data_value);
|
||||
equipment_data = 0;
|
||||
if(!data_analysis_flag)
|
||||
device_flag = 1;
|
||||
}else if(mac_data){
|
||||
tire_pressure_data_analysis(tlv_data_value);
|
||||
mac_data = 0;
|
||||
}else
|
||||
}else{
|
||||
data_analysis(tlv_data_value);
|
||||
if(!data_analysis_flag)
|
||||
data_analysis_flag = 1;
|
||||
}
|
||||
// }else{
|
||||
//DEBUG_PRINT("\nuartrx[i] = %x .\n",uartrx[i]);
|
||||
}
|
||||
}else{
|
||||
printf("\nuartrx[i] = %x .\n",uartrx[i]);
|
||||
}
|
||||
upgrade_state=0;
|
||||
str_len = 0;
|
||||
data_len = 0;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
|
||||
switch (uup_rx_state) {
|
||||
case 0:
|
||||
if (uartrx[i] == 0x7e)
|
||||
@ -272,22 +276,20 @@ static void protocol_uart_rx_thread(void *param)
|
||||
case 6:
|
||||
if (uartrx[i] == Get_sys_softwar_order()){
|
||||
if(Get_sys_veer_velocity()){
|
||||
//DEBUG_PRINT("error ota sj. Speed present\n");
|
||||
ota_request[1] = 0x01;
|
||||
ota_request[6] = Get_sys_softwar_host();
|
||||
ota_request[7] = Get_sys_softwar_order();
|
||||
TXCMD_Other_Set(ota_request,8);
|
||||
printf("error ota sj. Speed present\n");
|
||||
// ota_request[1] = 0x01;
|
||||
// ota_request[6] = Get_sys_softwar_host();
|
||||
// ota_request[7] = Get_sys_softwar_order();
|
||||
// TXCMD_Other_Set(ota_request,8);
|
||||
Send_ota_state(1);
|
||||
}else{
|
||||
//DEBUG_PRINT("enter ota sj.\n");
|
||||
printf("enter ota sj.\n");
|
||||
Set_sys_power_on_self_test(150);
|
||||
// extern uint8_t now_theme_state;
|
||||
// now_theme_state = 5;
|
||||
Set_sys_upgrade_Flag(1);//进入ota界面
|
||||
|
||||
ota_request[6] = Get_sys_softwar_host();
|
||||
ota_request[7] = Get_sys_softwar_order();
|
||||
vTaskDelay(100);
|
||||
TXCMD_Other_Set(ota_request,8);
|
||||
// ota_request[6] = Get_sys_softwar_host();
|
||||
// ota_request[7] = Get_sys_softwar_order();
|
||||
Send_ota_state(0);
|
||||
|
||||
if(timeout)
|
||||
timeout=0;
|
||||
@ -297,9 +299,20 @@ static void protocol_uart_rx_thread(void *param)
|
||||
uup_rx_state = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if((!data_analysis_flag) && data_count_flag == 50){
|
||||
data_count_flag = 0;
|
||||
if(uart3_flag){
|
||||
printf("uart3 open .\r\n");
|
||||
UART3_Type_regression();
|
||||
uart3_flag = 0;
|
||||
}else{
|
||||
printf("uart3 close .\r\n");
|
||||
UART3_Modification_Type();
|
||||
uart3_flag = 1;
|
||||
}
|
||||
}
|
||||
}else{//升级逻辑
|
||||
timeout ++;
|
||||
for (i = 0; i < len; i++) {
|
||||
@ -335,7 +348,7 @@ static void protocol_uart_rx_thread(void *param)
|
||||
//uup_rx_data_len |= uartrx[i];
|
||||
uup_rx_data_len = (uartrx[i]<<8) | uup_rx_data_len;
|
||||
if((uup_rx_data_len > UUP_PACKET_A27_SIZE + 2)) { //4096 + 2
|
||||
//DEBUG_PRINT("Invalid uup_rx_data_len %d\n", uup_rx_data_len);
|
||||
printf("Invalid uup_rx_data_len %d\n", uup_rx_data_len);
|
||||
uup_rx_state = 0;
|
||||
} else {
|
||||
uup_rx_state++;
|
||||
@ -365,27 +378,25 @@ static void protocol_uart_rx_thread(void *param)
|
||||
len = buf[3]<<8 | len;
|
||||
for (i = 0; i < len + 4; i++)
|
||||
checksum ^= buf[i];
|
||||
////DEBUG_PRINT("checksum = 0x%x , buf[len + 4] = 0x%x\n",checksum,buf[len + 4]);
|
||||
//printf("checksum = 0x%x , buf[len + 4] = 0x%x\n",checksum,buf[len + 4]);
|
||||
if (checksum == buf[len + 4]) {
|
||||
timeout =0;
|
||||
// uup_ota_update(uap, buf + 4, len);
|
||||
//DEBUG_PRINT("rev frame checksum err.\n");
|
||||
uup_ota_update(uap, buf + 4, len);
|
||||
} else {
|
||||
printf("rev frame checksum err.\r\n");
|
||||
}
|
||||
uup_rx_tail = (uup_rx_tail + 1) % UUP_RX_FRAME_NUM;
|
||||
}
|
||||
|
||||
if(timeout >= 3000){//超时退出升级 大约40s
|
||||
//DEBUG_PRINT("exit ota sj.\n");
|
||||
printf("exit ota sj.\n");
|
||||
Set_sys_power_on_self_test(100);
|
||||
Set_sys_upgrade_Flag(2);
|
||||
//DEBUG_PRINT("UART3_Type_regression .\n");
|
||||
printf("UART3_Type_regression .\n");
|
||||
extern void UART3_Type_regression(void);
|
||||
UART3_Type_regression();
|
||||
timeout = 0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@
|
||||
//
|
||||
//#define configTOTAL_HEAP_SIZE ( ( size_t ) ( (18.8+32) * 1024 * 1024) ) // google拼音出现异常
|
||||
//#define configTOTAL_HEAP_SIZE ( ( size_t ) ( (8.5+32) * 1024 * 1024) ) // google拼音正常工作
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( (3.5+32) * 1024 * 1024) ) // google拼音正常工作
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( (3.5+30) * 1024 * 1024) ) // google拼音正常工作
|
||||
|
||||
#elif defined(REVERSE_TRACK)
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( (22+32) * 1024 * 1024) )
|
||||
|
@ -89,8 +89,35 @@ struct IAACallbacks
|
||||
void* cb_ctx;
|
||||
};
|
||||
|
||||
typedef struct __auto_cfg_info
|
||||
{
|
||||
short width;//pixel
|
||||
short height;
|
||||
short density;
|
||||
short fps;
|
||||
char* wifi_ssid;
|
||||
char* wifi_passwd;
|
||||
char wifi_channel;
|
||||
bool disable_auto_audio;
|
||||
bool video_auto_start;
|
||||
|
||||
} auto_cfg_info;
|
||||
|
||||
extern auto_cfg_info *g_auto_link_info;
|
||||
|
||||
int android_auto_init(struct IAACallbacks* cbs);
|
||||
int android_auto_rfcomm_read_data_proc(char *buf, int len);
|
||||
void android_auto_start();
|
||||
void android_auto_set_rfcomm_info(const char * ssid, const char * passwd, const char * mac, int securityMode, const char * ip, int port);
|
||||
void android_auto_set_BT_paring_status(bool paired, const char *pinCode, int status);
|
||||
void android_auto_send_touch_event(unsigned int x, unsigned int y, int action);
|
||||
void android_auto_send_key_event(unsigned int keycode, int press);
|
||||
void android_auto_send_knob_event(unsigned int keycode, int delta);
|
||||
void android_auto_set_night_mode(bool night);
|
||||
|
||||
void android_auto_get_video_focus(int mode);
|
||||
void android_auto_release_video_focus(int mode);
|
||||
void android_auto_get_audio_focus(int mode);
|
||||
void android_auto_release_audio_focus(int mode);
|
||||
|
||||
#endif
|
302
app/carlink/AA/src/carlink_aa-bf.c
Normal file
@ -0,0 +1,302 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "carlink_video.h"
|
||||
#include "carlink_common.h"
|
||||
#include "AndroidAuto.h"
|
||||
#include "board.h"
|
||||
|
||||
#if CARLINK_AA
|
||||
|
||||
struct AAHandle
|
||||
{
|
||||
struct ICalinkEventCallbacks carlinkEventCB;
|
||||
struct IAACallbacks carlinkAACB;
|
||||
|
||||
bool mInitDone;
|
||||
bool mBTConnected;
|
||||
bool mRfcommReady;
|
||||
char mLocalBTMac[6];
|
||||
char mRemoteBTMac[6];
|
||||
char mIp[32];
|
||||
|
||||
};
|
||||
//extern int debug_buf_ref;
|
||||
|
||||
struct AAHandle gAACtx;
|
||||
static bool g_aa_disable = false;
|
||||
|
||||
|
||||
static void android_auto_notify_event(struct carlink_event *ev, enum CARLINK_EVENT_TYPE type, bool disable_filter)
|
||||
{
|
||||
ev->link_type = CARLINK_AUTO_WIRELESS;
|
||||
ev->disable_filter = disable_filter;
|
||||
ev->type = type;
|
||||
carlink_notify_event(ev);
|
||||
}
|
||||
|
||||
static void start_aa(struct AAHandle* pctx)
|
||||
{
|
||||
if (!pctx->mInitDone)
|
||||
return;
|
||||
//if (pctx->mBTConnected)
|
||||
// return;
|
||||
if (!pctx->mRfcommReady)
|
||||
return;
|
||||
if (g_aa_disable)
|
||||
return;
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
|
||||
g_auto_link_info->wifi_ssid = (char *)carlink_get_wifi_ssid();
|
||||
g_auto_link_info->wifi_passwd = (char *)carlink_get_wifi_passwd;
|
||||
android_auto_set_rfcomm_info((const char*)carlink_get_wifi_ssid(),
|
||||
(const char*)carlink_get_wifi_passwd(), (const char*)carlink_get_wifi_mac(), 5, (const char*)pctx->mIp, 0);
|
||||
android_auto_start();
|
||||
}
|
||||
|
||||
static void onEventAA(void* ctx, const struct carlink_event *ev)
|
||||
{
|
||||
enum CARLINK_EVENT_TYPE type;
|
||||
struct AAHandle* pctx = (struct AAHandle*)ctx;
|
||||
if (NULL == ev)
|
||||
return;
|
||||
if (ev->link_type != CARLINK_AUTO_WIRELESS && !ev->disable_filter)// skip not aa event
|
||||
return;
|
||||
|
||||
type = ev->type;
|
||||
|
||||
switch (type) {
|
||||
case -1: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_INIT_DONE:
|
||||
pctx->mInitDone = true;
|
||||
start_aa(pctx);
|
||||
break;
|
||||
case CARLINK_EVENT_BT_CONNECT: {
|
||||
pctx->mBTConnected = true;
|
||||
start_aa(pctx);
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_BT_AA_RFCOMM_READY: {
|
||||
pctx->mRfcommReady = true;
|
||||
start_aa(pctx);
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_BT_DISCONNECT: {
|
||||
pctx->mBTConnected = false;
|
||||
pctx->mRfcommReady = false;
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_WIFI_CONNECT: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_MSG_SESSION_CONNECT: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_MSG_SESSION_STOP: {
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
start_aa(pctx);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void aa_rfcomm_data_read(void* ctx, const void* buf, int len)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)ctx;
|
||||
|
||||
if (!pctx->mRfcommReady)
|
||||
return;
|
||||
|
||||
android_auto_rfcomm_read_data_proc((char*)buf, len);
|
||||
}
|
||||
|
||||
static int rf_write_transfer_cb(void* cb_ctx, char *buf, int len)
|
||||
{
|
||||
int ret = -1;
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
if (!pctx->mRfcommReady)
|
||||
return -1;
|
||||
ret = carlink_auto_rfcomm_data_write(buf, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void video_init_impl(void* cb_ctx, int w, int h, int x, int y)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
printf("x:%d y:%d w:%d h:%d\r\n", x, y, w, h);
|
||||
set_carlink_active_video_info(x, y);
|
||||
h264_dec_ctx_init();
|
||||
set_carlink_display_state(1);
|
||||
//debug_buf_ref = 1;
|
||||
}
|
||||
|
||||
static void video_uninit_impl(void* cb_ctx)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
set_carlink_display_state(0);
|
||||
set_carlink_active_video_info(0, 0);
|
||||
}
|
||||
|
||||
int g_v_count;
|
||||
static void video_play_impl(void* cb_ctx, char *buf, int len)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
video_frame_s* frame = NULL;
|
||||
|
||||
get_retry:
|
||||
frame = get_h264_frame_buf();
|
||||
if (NULL == frame) {
|
||||
//printf("h264 frame is empty\r\n");
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
goto get_retry;
|
||||
//continue;
|
||||
}
|
||||
|
||||
memcpy(frame->cur, buf, len);
|
||||
frame->len = len;
|
||||
|
||||
notify_h264_frame_ready(&frame);
|
||||
if (g_v_count++ > 50) {
|
||||
//android_auto_get_video_focus(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void audio_init_callback_impl(void* cb_ctx, int type, int sample, int ch, int bits)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
}
|
||||
static void audio_uninit_callback_impl(void* cb_ctx, int type)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
}
|
||||
static void audio_play_impl(void* cb_ctx, int type, char *buf, int len)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
}
|
||||
|
||||
static void mic_init_callback_impl(void* cb_ctx, int sample, int ch, int bits)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
}
|
||||
static void mic_uninit_callback_impl(void* cb_ctx)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
}
|
||||
static void mic_capture_impl(void* cb_ctx, char *buf, int len)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
}
|
||||
|
||||
static void bt_paring_request_callback_impl(void* cb_ctx, const char *phoneAddr, int pairingMethod)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
}
|
||||
|
||||
static void status_notify_impl(void* cb_ctx, int status_type)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
struct carlink_event ev = {0};
|
||||
|
||||
if (status_type == LINK_REMOVED) {
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
android_auto_notify_event(&ev, CARLINK_EVENT_MSG_SESSION_STOP, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void json_msg_notify_impl(void* cb_ctx, char *buf, int len)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int carlink_aa_init()
|
||||
{
|
||||
int ret = -1;
|
||||
struct AAHandle* pctx = &gAACtx;
|
||||
struct IAACallbacks* carlinkAACBPtr = NULL;
|
||||
|
||||
memset((void*)pctx, 0, sizeof(struct AAHandle));
|
||||
|
||||
|
||||
g_auto_link_info->width = CARLINK_VIDEO_WIDTH;
|
||||
g_auto_link_info->height = CARLINK_VIDEO_HEIGHT;
|
||||
g_auto_link_info->fps = 30;
|
||||
g_auto_link_info->density = 160;
|
||||
g_auto_link_info->disable_auto_audio = 1;
|
||||
g_auto_link_info->video_auto_start = 1;
|
||||
|
||||
set_carlink_display_info(0, 0, CARLINK_VIDEO_WIDTH, CARLINK_VIDEO_HEIGHT);
|
||||
set_carlink_video_info(CARLINK_VIDEO_WIDTH, CARLINK_VIDEO_HEIGHT, 30);
|
||||
|
||||
ret = carlink_common_init();
|
||||
|
||||
pctx->carlinkEventCB.onEvent = onEventAA;
|
||||
pctx->carlinkEventCB.rfcomm_data_read = aa_rfcomm_data_read;
|
||||
pctx->carlinkEventCB.cb_ctx = (void*)pctx;
|
||||
|
||||
carlink_register_event_callbacks(&pctx->carlinkEventCB);
|
||||
|
||||
ret = carlink_bt_wifi_init();
|
||||
|
||||
carlinkAACBPtr = &pctx->carlinkAACB;
|
||||
carlinkAACBPtr->video_init = video_init_impl;
|
||||
carlinkAACBPtr->video_uninit = video_uninit_impl;
|
||||
carlinkAACBPtr->video_play = video_play_impl;
|
||||
carlinkAACBPtr->audio_init_callback = audio_init_callback_impl;
|
||||
carlinkAACBPtr->audio_uninit_callback = audio_uninit_callback_impl;
|
||||
carlinkAACBPtr->mic_init_callback = mic_init_callback_impl;
|
||||
carlinkAACBPtr->mic_uninit_callback = mic_uninit_callback_impl;
|
||||
carlinkAACBPtr->mic_capture = mic_capture_impl;
|
||||
carlinkAACBPtr->bt_paring_request_callback = bt_paring_request_callback_impl;
|
||||
carlinkAACBPtr->status_notify = status_notify_impl;
|
||||
carlinkAACBPtr->json_msg_notify = json_msg_notify_impl;
|
||||
|
||||
carlinkAACBPtr->rf_read_transfer_cb = NULL;
|
||||
carlinkAACBPtr->rf_write_transfer_cb = rf_write_transfer_cb;
|
||||
carlinkAACBPtr->cb_ctx = (void*)pctx;
|
||||
ret = android_auto_init(&pctx->carlinkAACB);
|
||||
{
|
||||
char ip[4] = {0};
|
||||
carlink_get_ap_ip_addr(ip);
|
||||
sprintf(pctx->mIp, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
struct carlink_event ev = {0};
|
||||
android_auto_notify_event(&ev, CARLINK_EVENT_INIT_DONE, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void carlink_aa_enable(int enable)
|
||||
{
|
||||
if (enable) {
|
||||
g_aa_disable = false;
|
||||
} else {
|
||||
g_aa_disable = true;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
int carlink_aa_init()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void carlink_aa_enable(int enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -12,7 +12,6 @@ struct AAHandle
|
||||
struct ICalinkEventCallbacks carlinkEventCB;
|
||||
struct IAACallbacks carlinkAACB;
|
||||
|
||||
|
||||
bool mInitDone;
|
||||
bool mBTConnected;
|
||||
bool mRfcommReady;
|
||||
@ -21,8 +20,11 @@ struct AAHandle
|
||||
char mIp[32];
|
||||
|
||||
};
|
||||
//extern int debug_buf_ref;
|
||||
|
||||
struct AAHandle gAACtx;
|
||||
static bool g_aa_disable = false;
|
||||
|
||||
|
||||
static void android_auto_notify_event(struct carlink_event *ev, enum CARLINK_EVENT_TYPE type, bool disable_filter)
|
||||
{
|
||||
@ -40,7 +42,12 @@ static void start_aa(struct AAHandle* pctx)
|
||||
// return;
|
||||
if (!pctx->mRfcommReady)
|
||||
return;
|
||||
if (g_aa_disable)
|
||||
return;
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
|
||||
g_auto_link_info->wifi_ssid = (char *)carlink_get_wifi_ssid();
|
||||
g_auto_link_info->wifi_passwd = (char *)carlink_get_wifi_passwd;
|
||||
android_auto_set_rfcomm_info((const char*)carlink_get_wifi_ssid(),
|
||||
(const char*)carlink_get_wifi_passwd(), (const char*)carlink_get_wifi_mac(), 5, (const char*)pctx->mIp, 0);
|
||||
android_auto_start();
|
||||
@ -119,12 +126,17 @@ static int rf_write_transfer_cb(void* cb_ctx, char *buf, int len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int g_v_count;
|
||||
static void video_init_impl(void* cb_ctx, int w, int h, int x, int y)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
printf("x:%d y:%d w:%d h:%d\r\n", x, y, w, h);
|
||||
set_carlink_active_video_info(x, y);
|
||||
h264_dec_ctx_init();
|
||||
set_carlink_display_state(1);
|
||||
//carlink_bt_close();
|
||||
g_v_count = 0;
|
||||
//debug_buf_ref = 1;
|
||||
}
|
||||
|
||||
static void video_uninit_impl(void* cb_ctx)
|
||||
@ -132,6 +144,7 @@ static void video_uninit_impl(void* cb_ctx)
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
set_carlink_display_state(0);
|
||||
set_carlink_active_video_info(0, 0);
|
||||
}
|
||||
|
||||
static void video_play_impl(void* cb_ctx, char *buf, int len)
|
||||
@ -153,6 +166,9 @@ get_retry:
|
||||
frame->len = len;
|
||||
|
||||
notify_h264_frame_ready(&frame);
|
||||
if (g_v_count++ > 50) {//enable_malloc_debug = 1;
|
||||
//android_auto_get_video_focus(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void audio_init_callback_impl(void* cb_ctx, int type, int sample, int ch, int bits)
|
||||
@ -204,7 +220,7 @@ static void json_msg_notify_impl(void* cb_ctx, char *buf, int len)
|
||||
|
||||
|
||||
|
||||
int carlink_aa_init()
|
||||
int _carlink_aa_init()
|
||||
{
|
||||
int ret = -1;
|
||||
struct AAHandle* pctx = &gAACtx;
|
||||
@ -212,6 +228,14 @@ int carlink_aa_init()
|
||||
|
||||
memset((void*)pctx, 0, sizeof(struct AAHandle));
|
||||
|
||||
|
||||
g_auto_link_info->width = CARLINK_VIDEO_WIDTH;
|
||||
g_auto_link_info->height = CARLINK_VIDEO_HEIGHT;
|
||||
g_auto_link_info->fps = 30;
|
||||
g_auto_link_info->density = 160;
|
||||
g_auto_link_info->disable_auto_audio = 1;
|
||||
g_auto_link_info->video_auto_start = 1;
|
||||
|
||||
set_carlink_display_info(0, 0, CARLINK_VIDEO_WIDTH, CARLINK_VIDEO_HEIGHT);
|
||||
set_carlink_video_info(CARLINK_VIDEO_WIDTH, CARLINK_VIDEO_HEIGHT, 30);
|
||||
|
||||
@ -255,10 +279,41 @@ int carlink_aa_init()
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void taskInitCarlinkAA(void* param)
|
||||
{
|
||||
_carlink_aa_init();
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
|
||||
int carlink_aa_init()
|
||||
{
|
||||
xTaskCreate(taskInitCarlinkAA, "initThread", 2048 * 4, NULL, 1, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void carlink_aa_enable(int enable)
|
||||
{
|
||||
if (enable) {
|
||||
g_aa_disable = false;
|
||||
} else {
|
||||
g_aa_disable = true;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
int carlink_aa_init()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void carlink_aa_enable(int enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
133
app/carlink/CP/include/mycommon.h
Normal file
@ -0,0 +1,133 @@
|
||||
#ifndef MYCOMMON_H_H
|
||||
#define MYCOMMON_H_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef CAPLAY_LINK_TYPE
|
||||
#define CAPLAY_LINK_TYPE
|
||||
typedef enum
|
||||
{
|
||||
CARPLAY = 0x00,
|
||||
CARLIFE,
|
||||
ANDROID_CARLIFE,
|
||||
ANDROID_MIRROR = 3,
|
||||
IOS_CARLIFE,
|
||||
ANDROID_AUTO = 5,
|
||||
ECLINK = 0x06,
|
||||
CARPLAY_WIRELESS
|
||||
}Link_TYPE;
|
||||
#endif
|
||||
|
||||
//general function
|
||||
typedef enum __USB_MODE
|
||||
{
|
||||
UNDEFINED = 0,
|
||||
HOST,
|
||||
PERIPHERAL,
|
||||
OTG
|
||||
}USB_MODE;
|
||||
|
||||
#define LOGV(...) printf(__VA_ARGS__); printf("\r\n");
|
||||
|
||||
struct view_area
|
||||
{
|
||||
short w;
|
||||
short h;
|
||||
short x;
|
||||
short y;
|
||||
};
|
||||
|
||||
typedef struct __cfg_info
|
||||
{
|
||||
char *iap2_name;
|
||||
char *iap2_modelIdentifier;
|
||||
char *iap2_manfacturer;
|
||||
char *iap2_serialnumber;
|
||||
char *iap2_sw_ver;
|
||||
char *iap2_hw_ver;
|
||||
char *iap2_vehicleInfo_name;
|
||||
char *iap2_product_uuid;
|
||||
char *iap2_usb_serial_num;
|
||||
|
||||
char *manfacturer;
|
||||
char *oem_icon_label;
|
||||
char *oem_icon_path;
|
||||
char *os_info;
|
||||
char *iOSVersionMin;
|
||||
char *limited_ui_elements;
|
||||
char *guuid;
|
||||
char *devid;
|
||||
char link_type;
|
||||
char btmac[6];
|
||||
bool oem_icon_visible;
|
||||
bool limited_ui;
|
||||
bool right_hand_driver;
|
||||
bool night_mode;
|
||||
bool has_knob;
|
||||
bool has_telbutton;
|
||||
bool has_mediabutton;
|
||||
bool has_proxsensor;
|
||||
bool has_EnhancedReqCarUI;
|
||||
bool has_ETCSupported;
|
||||
bool HiFiTouch;
|
||||
bool LoFiTouch;
|
||||
unsigned short usb_country_code;
|
||||
unsigned short tp_verndor_code;
|
||||
unsigned short tp_product_code;
|
||||
unsigned short tel_verndor_code;
|
||||
unsigned short tel_product_code;
|
||||
unsigned short knob_verndor_code;
|
||||
unsigned short knob_product_code;
|
||||
unsigned short proxsensor_verndor_code;
|
||||
unsigned short proxsensor_product_code;
|
||||
short width;//pixel
|
||||
short height;
|
||||
short fps;
|
||||
short screen_width_phy;//mm
|
||||
short screen_height_phy;
|
||||
|
||||
char encrypt_ic_i2c_bus_num;
|
||||
char encrypt_ic_addr;
|
||||
char usb_idx;
|
||||
char need_sw_aec;
|
||||
char aec_delay;
|
||||
bool tvout_enable;
|
||||
|
||||
bool use_remote_audio;
|
||||
char video_type;
|
||||
short icurrent;
|
||||
int duck_vol;
|
||||
|
||||
char enable_iap_carplay_sess;
|
||||
char *keychain_path_dir;
|
||||
|
||||
char* wifi_ssid;
|
||||
char* wifi_passwd;
|
||||
char* public_key;
|
||||
char* src_version;
|
||||
char ip_v4_addr[4];
|
||||
char wifi_channel;
|
||||
short net_port;
|
||||
|
||||
char carplay_net_ready;
|
||||
char disable_bonjour;
|
||||
char iap_carplay_rej;
|
||||
|
||||
bool enable_enhanced_siri;
|
||||
bool enable_single_ui;
|
||||
|
||||
bool is_old_carplay_ver;
|
||||
|
||||
struct view_area area[3];
|
||||
char view_area_index;
|
||||
|
||||
}cfg_info;
|
||||
|
||||
extern cfg_info *g_link_info;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -36,6 +36,8 @@ struct carplay_ctx
|
||||
};
|
||||
|
||||
struct carplay_ctx g_cp_handle;
|
||||
static bool g_cp_disable = false;
|
||||
|
||||
|
||||
static void carplay_init_parameter();
|
||||
void start_mdnsd();
|
||||
@ -56,9 +58,22 @@ static void iap2_link_status(void *ctx, IAP2_LINK_STATUS status){}
|
||||
static int iap2_write_data(void *ctx, char *buf, int len)
|
||||
{
|
||||
(void)ctx;
|
||||
printf("iap2_write_data --------------------------\r\n");
|
||||
return carlink_iap_data_write((unsigned char *)buf, len);
|
||||
}
|
||||
static void iap2_msg_time_update(void *ctx, long long time, int zone_offset){}
|
||||
extern uint32_t tire_front_time;
|
||||
extern uint32_t tire_rear_time;
|
||||
extern uint32_t fml_stamp_to_time(uint32_t timep , uint32_t time[]);
|
||||
static void iap2_msg_time_update(void *ctx, long long time, int zone_offset){
|
||||
(void)ctx;
|
||||
printf("iap2_msg_time_update time ======================================== %lld , %d\r\n",time,zone_offset);
|
||||
uint32_t time_transfer[6];
|
||||
uint32_t sum = (uint32_t)time;
|
||||
|
||||
tire_rear_time = sum;
|
||||
tire_front_time = sum;
|
||||
fml_stamp_to_time(sum,time_transfer);
|
||||
}
|
||||
static void iap2_msg_gps(void *ctx, unsigned char session, int start){}
|
||||
static void iap2_msg_gps_gprmc_data_status(void *ctx, int value_a, int value_v, int value_x){}
|
||||
static void iap2_msg_identify(void *ctx, int type, int ok)
|
||||
@ -163,6 +178,9 @@ static void start_cp(struct carplay_ctx* pctx)
|
||||
if (pctx->mCarplayConnected)
|
||||
return;
|
||||
|
||||
if (g_cp_disable)
|
||||
return;
|
||||
|
||||
g_link_info->enable_iap_carplay_sess = 1;
|
||||
g_link_info->is_old_carplay_ver = 0;
|
||||
g_link_info->wifi_passwd = (char *)carlink_get_wifi_passwd();
|
||||
@ -270,6 +288,7 @@ static void taskInitCarlinkCpProc(void* param)
|
||||
|
||||
(void)param;
|
||||
|
||||
|
||||
iap2_callbacks iap2_cbs;
|
||||
memset((void *)&iap2_cbs, 0, sizeof(iap2_cbs));
|
||||
iap2_cbs.iap2_link_status_cb = iap2_link_status;
|
||||
@ -388,8 +407,8 @@ static void carplay_init_parameter()
|
||||
g_link_info->width = CARLINK_VIDEO_WIDTH;//pixel
|
||||
g_link_info->height = CARLINK_VIDEO_HEIGHT;
|
||||
g_link_info->fps = 30;
|
||||
g_link_info->screen_width_phy = PHYSICAL_WIDTH;//mm
|
||||
g_link_info->screen_height_phy = PHYSICAL_HEIGHT;
|
||||
g_link_info->screen_width_phy = CARLINK_VIDEO_WIDTH;
|
||||
g_link_info->screen_height_phy = CARLINK_VIDEO_HEIGHT;
|
||||
|
||||
g_link_info->icurrent = 1000;
|
||||
g_link_info->enable_iap_carplay_sess = 1;
|
||||
@ -424,6 +443,16 @@ int carlink_cp_init()
|
||||
return 0;
|
||||
}
|
||||
|
||||
void carlink_cp_enable(int enable)
|
||||
{
|
||||
if (enable) {
|
||||
g_cp_disable = false;
|
||||
} else {
|
||||
g_cp_disable = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//int mdnsd_task();
|
||||
static void taskMdnsdProc(void* param)
|
||||
{
|
||||
@ -442,5 +471,11 @@ int carlink_cp_init()
|
||||
return 0;
|
||||
}
|
||||
|
||||
void carlink_cp_enable(int enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -2,5 +2,6 @@
|
||||
#define _CARLINK_CP_H_
|
||||
|
||||
int carlink_cp_init();
|
||||
void carlink_cp_enable(int enable);
|
||||
|
||||
#endif
|
||||
|
393
app/carlink/CP/src/carlink_cp_bt_wifi.c
Normal file
@ -0,0 +1,393 @@
|
||||
//#include "os_adapt.h"
|
||||
#include <FreeRTOS_POSIX.h>
|
||||
#include <task.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "board.h"
|
||||
#include "timer.h"
|
||||
#include "iot_wifi.h"
|
||||
#include "mmcsd_core.h"
|
||||
#include "carlink_utils.h"
|
||||
#include "console.h"
|
||||
#include "fsc_bt.h"
|
||||
#include "iap.h"
|
||||
|
||||
#if !defined(USE_LWIP) || !USE_LWIP
|
||||
#error "Carplay need lwip!"
|
||||
#endif
|
||||
|
||||
#include "ethernet.h"
|
||||
#include "tcpip.h"
|
||||
#include "lwip/apps/lwiperf.h"
|
||||
#include "dhcp.h"
|
||||
|
||||
#include "carlink_video.h"
|
||||
#include "mycommon.h"
|
||||
#include "wifi_conf.h"
|
||||
#include "carlink_cp_priv.h"
|
||||
//#define USE_WLAN_STA
|
||||
|
||||
|
||||
static char g_cp_bt_mac[13] = {0};
|
||||
static bool g_cp_bt_mac_ready = false;
|
||||
|
||||
static uint8_t cp_ap_ssid[64] = {"ap63011"};
|
||||
static uint8_t cp_ap_passwd[16] = {"88888888"};
|
||||
extern int wps_connect_done;
|
||||
|
||||
|
||||
static const uint8_t ucIPAddress[4] = {192, 168, 13, 1};
|
||||
static const uint8_t ucNetMask[4] = {255, 255, 255, 0};
|
||||
static const uint8_t ucGatewayAddress[4] = {0, 0, 0, 0};
|
||||
static int lwip_tcpip_init_done_flag = 0;
|
||||
|
||||
//static int g_bt_iap_ready = 0;
|
||||
//static int g_dhcp_client_cp_ready = 0;
|
||||
|
||||
static struct netif gnetif[4];
|
||||
|
||||
extern int wifi_add_custom_ie(void *cus_ie, int ie_num);
|
||||
int mmcsd_wait_sdio_ready(int32_t timeout);
|
||||
static void cp_reset_wifi_ap_info(const char *prefex);
|
||||
static void cp_start_wlan();
|
||||
extern err_t dhcp_server_start(struct netif *netif, ip4_addr_t *start, ip4_addr_t *end);
|
||||
extern err_t wlan_ethernetif_init(struct netif *netif);
|
||||
#define lwip_ipv4_addr(addr) ((addr[0]) | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24))
|
||||
|
||||
|
||||
static void tcpip_init_done(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
//lwip_tcpip_init_done_flag = 1;
|
||||
}
|
||||
|
||||
void lwiperf_report_cb_impl(void *arg, enum lwiperf_report_type report_type,
|
||||
const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port,
|
||||
u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
printf("lwiperf_report_cb_impl bytes:%d %d ms \r\n", bytes_transferred, ms_duration);
|
||||
}
|
||||
|
||||
int cp_wlan_tcp_ip_is_ready()
|
||||
{
|
||||
return lwip_tcpip_init_done_flag;
|
||||
}
|
||||
|
||||
//dd3000a0400000020022020961726B6D6963726F0003064C696E75780004030102030606ffffffffffff070666fadde250c0
|
||||
static u8 carplay_vendor_ie[] = {
|
||||
0xdd, 0x30, 0x00, 0xa0, 0x40, 0x00, 0x00, 0x02, 0x00, 0x22, 0x02, 0x09, 0x61, 0x72, 0x6B, 0x6D,
|
||||
0x69, 0x63, 0x72, 0x6F, 0x00, 0x03, 0x06, 0x4C, 0x69, 0x6E, 0x75, 0x78, 0x00, 0x04, 0x03, 0x01,
|
||||
0x02, 0x03, 0x06, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x06, 0x66, 0xfa, 0xdd, 0xe2,
|
||||
0x50, 0xc0
|
||||
};
|
||||
rtw_custom_ie_t carplay_ie[1] = {{carplay_vendor_ie, PROBE_RSP | BEACON}};
|
||||
|
||||
void carplay_add_vendor_ie()
|
||||
{
|
||||
wifi_add_custom_ie((void *)carplay_ie, 1);
|
||||
}
|
||||
|
||||
void carplay_ie_replace_bt_mac(const char* btmac_str, int btmac_str_len)
|
||||
{
|
||||
char btmac[6] = {0};
|
||||
string2hex((char *)btmac_str, btmac_str_len, btmac, 6);
|
||||
memcpy((void*)g_link_info->btmac, (void*)btmac, 6);
|
||||
//sscanf(btmac_str, "%02x%02x%02x%02x%02x%02x", btmac[0], btmac[1], btmac[2], btmac[3], btmac[4], btmac[5]);
|
||||
carplay_vendor_ie[36] = btmac[0];
|
||||
carplay_vendor_ie[37] = btmac[1];
|
||||
carplay_vendor_ie[38] = btmac[2];
|
||||
carplay_vendor_ie[39] = btmac[3];
|
||||
carplay_vendor_ie[40] = btmac[4];
|
||||
carplay_vendor_ie[41] = btmac[5];
|
||||
//memcpy((void*)(carplay_vendor_ie + 36), (void*)btmac, 6);
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sizeof(carplay_vendor_ie); i++) {
|
||||
printf("0x%02x, ", carplay_vendor_ie[i]);
|
||||
}printf("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(USE_WLAN_STA)
|
||||
static void dump_ip_addr(const char *msg, const ip_addr_t *server_addr)
|
||||
{
|
||||
printf("%s %d.%d.%d.%d \r\n", msg,
|
||||
ip4_addr1_16(ip_2_ip4(server_addr)), ip4_addr2_16(ip_2_ip4(server_addr)), ip4_addr3_16(ip_2_ip4(server_addr)), ip4_addr4_16(ip_2_ip4(server_addr)));
|
||||
}
|
||||
|
||||
static void cp_dhcp_client_status_callback(struct netif *netif, int status, const ip_addr_t *server_addr)
|
||||
{
|
||||
if (&gnetif[0] == netif) {
|
||||
dump_ip_addr("dhcp server ip :", (const ip_addr_t *)server_addr);
|
||||
dump_ip_addr("dhcp client ip :", (const ip_addr_t *)&netif->ip_addr);
|
||||
dump_ip_addr("dhcp client netmask:", (const ip_addr_t *)&netif->netmask);
|
||||
dump_ip_addr("dhcp client gw :", (const ip_addr_t *)&netif->gw);
|
||||
ip_addr_t *server_addr1 = (ip_addr_t *)&netif->ip_addr;
|
||||
g_link_info->ip_v4_addr[0] = ip4_addr1_16(ip_2_ip4(server_addr1));
|
||||
g_link_info->ip_v4_addr[1] = ip4_addr2_16(ip_2_ip4(server_addr1));
|
||||
g_link_info->ip_v4_addr[2] = ip4_addr3_16(ip_2_ip4(server_addr1));
|
||||
g_link_info->ip_v4_addr[3] = ip4_addr4_16(ip_2_ip4(server_addr1));
|
||||
//g_dhcp_client_cp_ready = 1;
|
||||
|
||||
//if (g_bt_iap_ready)
|
||||
//carplay_start();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void restart_bt_wifi()
|
||||
{
|
||||
cp_bt_close();
|
||||
netif_set_down(&gnetif[0]);
|
||||
WIFI_Off();
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
cp_bt_open();
|
||||
start_ap(36, (const char *)cp_ap_ssid, (const char *)cp_ap_passwd, 1);
|
||||
carplay_add_vendor_ie();
|
||||
netif_set_default(&gnetif[0]);
|
||||
|
||||
netif_set_up(&gnetif[0]);
|
||||
}
|
||||
|
||||
static void cp_start_wlan()
|
||||
{
|
||||
char ap_prefix[5] = {0};
|
||||
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
ip4_addr_t dhcp_addr_start;
|
||||
ip4_addr_t dhcp_addr_end;
|
||||
|
||||
while(!g_cp_bt_mac_ready) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
memcpy(ap_prefix, g_cp_bt_mac + 8, 4);
|
||||
cp_reset_wifi_ap_info(ap_prefix);
|
||||
#if !defined(USE_WLAN_STA)
|
||||
start_ap(36, (const char *)cp_ap_ssid, (const char *)cp_ap_passwd, 1);
|
||||
#else
|
||||
//start_sta((const char *)cp_ap_ssid, (const char *)cp_ap_passwd, 1);
|
||||
dhcp_regisger_status_callback(cp_dhcp_client_status_callback);
|
||||
#endif
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
gw.addr = lwip_ipv4_addr(ucGatewayAddress);
|
||||
tcpip_init(tcpip_init_done, NULL);
|
||||
netif_add(&gnetif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, wlan_ethernetif_init, tcpip_input);
|
||||
|
||||
netif_set_default(&gnetif[0]);
|
||||
|
||||
#if !defined(USE_WLAN_STA)
|
||||
uint8_t addr_start[4] = {192, 168, 13, 20};
|
||||
uint8_t addr_end[4] = {192, 168, 13, 30};
|
||||
dhcp_addr_start.addr = lwip_ipv4_addr(addr_start);
|
||||
dhcp_addr_end.addr = lwip_ipv4_addr(addr_end);
|
||||
dhcp_server_start(&gnetif[0], &dhcp_addr_start, &dhcp_addr_end);
|
||||
//g_dhcp_client_cp_ready = 1;
|
||||
#endif
|
||||
|
||||
//netif_set_up(&gnetif[0]);
|
||||
lwiperf_start_tcp_server_default(lwiperf_report_cb_impl, NULL);
|
||||
lwip_tcpip_init_done_flag = 1;
|
||||
carplay_add_vendor_ie();
|
||||
}
|
||||
|
||||
void cp_wlan_start(void){
|
||||
netif_set_up(&gnetif[0]);
|
||||
}
|
||||
|
||||
|
||||
static void cp_reset_wifi_ap_info(const char *prefex)
|
||||
{
|
||||
if (prefex) {
|
||||
memset(cp_ap_ssid, 0, sizeof(cp_ap_ssid));
|
||||
sprintf((char *)cp_ap_ssid, "AP630_CP_%s", prefex);
|
||||
}
|
||||
g_link_info->wifi_passwd = cp_ap_passwd;
|
||||
g_link_info->wifi_ssid = cp_ap_ssid;
|
||||
g_link_info->wifi_channel = 36;
|
||||
g_link_info->ip_v4_addr[0] = ucIPAddress[0];
|
||||
g_link_info->ip_v4_addr[1] = ucIPAddress[1];
|
||||
g_link_info->ip_v4_addr[2] = ucIPAddress[2];
|
||||
g_link_info->ip_v4_addr[3] = ucIPAddress[3];
|
||||
}
|
||||
|
||||
static void cp_bt_callback(char * cAtStr)
|
||||
{
|
||||
char* cmd_para = NULL;
|
||||
printf("\r\nfsc_bt_callback_ec %s %d\r\n", cAtStr, strlen(cAtStr));
|
||||
struct cp_event ev;
|
||||
memset((void*)&ev, 0, sizeof(ev));
|
||||
ev.type = -1;
|
||||
|
||||
if (0) {
|
||||
} else if (0 == strncmp(cAtStr, "+IAPDATA=", 9)) {
|
||||
char ble_buf[256] = {0};
|
||||
int data_len, i;
|
||||
int data_str_len = (strlen(cAtStr) - 9);
|
||||
cmd_para = cAtStr + 9;
|
||||
data_len = data_str_len / 2;
|
||||
string2hex(cmd_para, data_str_len, ble_buf, data_len);
|
||||
for (i = 0; i < data_len; i++) {
|
||||
printf("%02x ", ble_buf[i]);
|
||||
}printf("\r\n");
|
||||
iap2_read_data_proc(ble_buf, data_len);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTDATA=", 10)) {
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSTAT=1",11)) {
|
||||
//ev.type = EC_EVENT_BT_DISCONNECT;
|
||||
printf("TRACE[%s][%d]:EC_EVENT_BT_DISCONNECT\r\n",__func__ ,__LINE__);
|
||||
ev.type = CP_EVENT_BT_DISCONNECT;
|
||||
carlink_cp_notify_event(&ev);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSTAT=3",11)) {
|
||||
printf("TRACE[%s][%d]:EC_EVENT_BT_CONNECT\r\n",__func__ ,__LINE__);
|
||||
|
||||
ev.type = CP_EVENT_BT_CONNECT;
|
||||
carlink_cp_notify_event(&ev);
|
||||
} else if (0 == strncmp(cAtStr, "+ADDR=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+NAME=AP630_CP_%s\r\n", (cAtStr + 6 + 8));
|
||||
printf("ADDR:%s\r\n", cAtStr + 6);
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
memset(cmd_str, 0, sizeof(cmd_str));
|
||||
sprintf(cmd_str, "AT+LENAME=AP630_CP_%s\r\n", (cAtStr + 6 + 8));
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
memcpy(g_cp_bt_mac, (cAtStr + 6), 12);
|
||||
carplay_ie_replace_bt_mac(cAtStr + 6, 12);
|
||||
g_cp_bt_mac_ready = true;
|
||||
} else if (0 == strncmp(cAtStr, "+VER", 4)) {
|
||||
char* cmd = "AT+ADDR\r\n";
|
||||
console_send_atcmd(cmd, strlen(cmd));//get mac addr
|
||||
} else if (0 == strncmp(cAtStr, "+NAME=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+LEADDR\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get LE addr
|
||||
} else if (0 == strncmp(cAtStr, "+LEADDR=", 6)) {
|
||||
char hexMacAddr[6] = {0};
|
||||
char m_tmp_buf[64] = {0};
|
||||
string2hex(&cAtStr[8], 12, hexMacAddr, sizeof(hexMacAddr));
|
||||
sprintf(m_tmp_buf, "AT+ADVDATA=%s\r\n", hexMacAddr);
|
||||
console_send_atcmd(m_tmp_buf, 19);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSENT=", 10)) {
|
||||
return;
|
||||
} else if (0 == strncmp(cAtStr, "+IAPSTAT=3", 10)) {
|
||||
//g_bt_iap_ready = 1;
|
||||
|
||||
//if (g_dhcp_client_cp_ready)
|
||||
//carplay_start();
|
||||
|
||||
ev.type = CP_EVENT_BT_IAP_READY;
|
||||
carlink_cp_notify_event(&ev);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int iap_data_write(unsigned char *data, int len)
|
||||
{
|
||||
uint8_t *at_str = NULL, *at_str_ptr = NULL;
|
||||
uint8_t *at_prefix = "AT+IAPSEND=";
|
||||
int prefix_len = strlen((char *)at_prefix);
|
||||
int cmd_len = (len * 2 + prefix_len + 2);
|
||||
|
||||
at_str = (uint8_t *)pvPortMalloc(cmd_len + 1);
|
||||
memset(at_str, 0, cmd_len + 1);
|
||||
if (NULL == at_str)
|
||||
return -1;
|
||||
at_str_ptr = at_str;
|
||||
sprintf((char*)at_str_ptr, "%s", (char*)at_prefix);
|
||||
at_str_ptr += prefix_len;
|
||||
hex2str(data, len, (char *)at_str_ptr);
|
||||
at_str_ptr += (len * 2);
|
||||
*at_str_ptr++ = '\r';
|
||||
*at_str_ptr++ = '\n';
|
||||
console_send_atcmd((char *)at_str, cmd_len);
|
||||
vPortFree(at_str);
|
||||
return len;
|
||||
}
|
||||
|
||||
void cp_bt_open()
|
||||
{
|
||||
char at_str[] = {"AT+BTEN=1\r\n"};
|
||||
console_send_atcmd((char *)at_str, strlen(at_str));
|
||||
}
|
||||
|
||||
void cp_bt_close()
|
||||
{
|
||||
char at_str[] = {"AT+BTEN=0\r\n"};
|
||||
console_send_atcmd((char *)at_str, strlen(at_str));
|
||||
}
|
||||
|
||||
|
||||
static void cp_wifi_event_handler( WIFIEvent_t * xEvent )
|
||||
{
|
||||
WIFIEventType_t xEventType = xEvent->xEventType;
|
||||
char mac_str[32] = {0};
|
||||
char *mac = NULL;
|
||||
|
||||
if (xEvent) {
|
||||
mac = xEvent->xInfo.xAPStationConnected.ucMac;
|
||||
sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
}
|
||||
|
||||
wps_connect_done = 0;
|
||||
|
||||
if (0) {
|
||||
} else if (eWiFiEventConnected == xEventType) {// meter is sta
|
||||
printf("\r\n The meter is connected to ap \r\n");
|
||||
} else if (eWiFiEventDisconnected == xEventType) {// meter is sta
|
||||
printf("\r\n The meter is disconnected from ap \r\n");
|
||||
} else if (eWiFiEventAPStationConnected == xEventType) {// meter is ap
|
||||
printf("\r\n The meter in AP is connected by sta %s \r\n", mac_str);
|
||||
} else if (eWiFiEventAPStationDisconnected == xEventType) {// meter is ap
|
||||
printf("\r\n The sta %s is disconnected from the meter \r\n", mac_str);
|
||||
}
|
||||
}
|
||||
|
||||
static BaseType_t cp_wifi_init()
|
||||
{
|
||||
int status;
|
||||
WIFI_Context_init();
|
||||
WIFI_RegisterEvent(eWiFiEventMax, cp_wifi_event_handler);
|
||||
for (;;) {
|
||||
status = mmcsd_wait_sdio_ready((int32_t)portMAX_DELAY);
|
||||
if (status == MMCSD_HOST_PLUGED) {
|
||||
printf("detect sdio device\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bt_set_support_carplay()
|
||||
{
|
||||
char cmd_str[64] = {0};
|
||||
|
||||
sprintf(cmd_str, "AT+PROFILE=33962\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));
|
||||
}
|
||||
|
||||
int carlink_cp_bt_wifi_init()
|
||||
{
|
||||
carlink_ey_video_init();
|
||||
cp_wifi_init();
|
||||
console_register_cb(NULL, cp_bt_callback);
|
||||
fsc_bt_main();
|
||||
bt_set_support_carplay();
|
||||
cp_bt_open();
|
||||
cp_start_wlan();
|
||||
printf("bt wlan init is ok\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
262
app/carlink/CP/src/carlink_cp_bt_wifi1.c
Normal file
@ -0,0 +1,262 @@
|
||||
#include "os_adapt.h"
|
||||
#include <FreeRTOS_POSIX.h>
|
||||
#include <task.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "board.h"
|
||||
#include "timer.h"
|
||||
#include "iot_wifi.h"
|
||||
#include "mmcsd_core.h"
|
||||
#include "carlink_utils.h"
|
||||
#include "console.h"
|
||||
#include "fsc_bt.h"
|
||||
#include "iap.h"
|
||||
|
||||
#if !defined(USE_LWIP) || !USE_LWIP
|
||||
#error "Carplay in freertos must use lwip!"
|
||||
#endif
|
||||
|
||||
#include "ethernet.h"
|
||||
#include "tcpip.h"
|
||||
#include "lwip/apps/lwiperf.h"
|
||||
#include "dhcp.h"
|
||||
|
||||
#include "carlink_video.h"
|
||||
#include "mycommon.h"
|
||||
|
||||
|
||||
static char g_cp_bt_mac[13] = {0};
|
||||
static bool g_cp_bt_mac_ready = false;
|
||||
|
||||
static uint8_t cp_ap_ssid[64] = {"ap63011"};
|
||||
static uint8_t cp_ap_passwd[16] = {"88888888"};
|
||||
extern int wps_connect_done;
|
||||
|
||||
|
||||
static const uint8_t ucIPAddress[4] = {192, 168, 13, 1};
|
||||
static const uint8_t ucNetMask[4] = {255, 255, 255, 0};
|
||||
static const uint8_t ucGatewayAddress[4] = {0, 0, 0, 0};
|
||||
static int lwip_tcpip_init_done_flag = 0;
|
||||
|
||||
static struct netif gnetif[4];
|
||||
|
||||
|
||||
int mmcsd_wait_sdio_ready(int32_t timeout);
|
||||
static void cp_reset_wifi_ap_info(const char *prefex);
|
||||
static void cp_start_wlan();
|
||||
extern err_t dhcp_server_start(struct netif *netif, ip4_addr_t *start, ip4_addr_t *end);
|
||||
extern err_t wlan_ethernetif_init(struct netif *netif);
|
||||
#define lwip_ipv4_addr(addr) ((addr[0]) | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24))
|
||||
|
||||
|
||||
static void tcpip_init_done(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
//lwip_tcpip_init_done_flag = 1;
|
||||
}
|
||||
|
||||
void lwiperf_report_cb_impl(void *arg, enum lwiperf_report_type report_type,
|
||||
const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port,
|
||||
u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
printf("lwiperf_report_cb_impl bytes:%d %d ms \r\n", bytes_transferred, ms_duration);
|
||||
}
|
||||
|
||||
int cp_wlan_tcp_ip_is_ready()
|
||||
{
|
||||
return lwip_tcpip_init_done_flag;
|
||||
}
|
||||
|
||||
static void cp_start_wlan()
|
||||
{
|
||||
const char *customer = "ark630hv100";
|
||||
char ap_prefix[5] = {0};
|
||||
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
ip4_addr_t dhcp_addr_start;
|
||||
ip4_addr_t dhcp_addr_end;
|
||||
|
||||
while(!g_cp_bt_mac_ready) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
memcpy(ap_prefix, g_cp_bt_mac + 8, 4);
|
||||
cp_reset_wifi_ap_info(ap_prefix);
|
||||
start_ap(36, (const char *)cp_ap_ssid, (const char *)cp_ap_passwd, 1);
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
gw.addr = lwip_ipv4_addr(ucGatewayAddress);
|
||||
tcpip_init(tcpip_init_done, NULL);
|
||||
netif_add(&gnetif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, wlan_ethernetif_init, tcpip_input);
|
||||
|
||||
netif_set_default(&gnetif[0]);
|
||||
|
||||
uint8_t addr_start[4] = {192, 168, 13, 20};
|
||||
uint8_t addr_end[4] = {192, 168, 13, 30};
|
||||
dhcp_addr_start.addr = lwip_ipv4_addr(addr_start);
|
||||
dhcp_addr_end.addr = lwip_ipv4_addr(addr_end);
|
||||
dhcp_server_start(&gnetif[0], &dhcp_addr_start, &dhcp_addr_end);
|
||||
|
||||
netif_set_up(&gnetif[0]);
|
||||
|
||||
lwiperf_start_tcp_server_default(lwiperf_report_cb_impl, NULL);
|
||||
lwip_tcpip_init_done_flag = 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void cp_reset_wifi_ap_info(const char *prefex)
|
||||
{
|
||||
memset(cp_ap_ssid, 0, sizeof(cp_ap_ssid));
|
||||
sprintf((char *)cp_ap_ssid, "AP630_%s", prefex);
|
||||
g_link_info->wifi_passwd = cp_ap_passwd;
|
||||
g_link_info->wifi_ssid = cp_ap_ssid;
|
||||
g_link_info->wifi_channel = 36;
|
||||
g_link_info->ip_v4_addr[0] = ucIPAddress[0];
|
||||
g_link_info->ip_v4_addr[1] = ucIPAddress[1];
|
||||
g_link_info->ip_v4_addr[2] = ucIPAddress[2];
|
||||
g_link_info->ip_v4_addr[3] = ucIPAddress[3];
|
||||
}
|
||||
|
||||
static void cp_bt_callback(char * cAtStr)
|
||||
{
|
||||
char* cmd_para = NULL;
|
||||
printf("\r\nfsc_bt_callback_ec %s %d\r\n", cAtStr, strlen(cAtStr));
|
||||
|
||||
if (0) {
|
||||
} else if (0 == strncmp(cAtStr, "+IAPDATA=", 9)) {
|
||||
char ble_buf[256] = {0};
|
||||
int data_len, i;
|
||||
int data_str_len = (strlen(cAtStr) - 9);
|
||||
cmd_para = cAtStr + 9;
|
||||
data_len = data_str_len / 2;
|
||||
string2hex(cmd_para, data_str_len, ble_buf, data_len);
|
||||
for (i = 0; i < data_len; i++) {
|
||||
printf("%02x ", ble_buf[i]);
|
||||
}printf("\r\n");
|
||||
iap2_read_data_proc(ble_buf, data_len);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTDATA=", 10)) {
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSTAT=1",11)) {
|
||||
//ev.type = EC_EVENT_BT_DISCONNECT;
|
||||
printf("TRACE[%s][%d]:EC_EVENT_BT_DISCONNECT\r\n",__func__ ,__LINE__);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSTAT=3",11)) {
|
||||
printf("TRACE[%s][%d]:EC_EVENT_BT_CONNECT\r\n",__func__ ,__LINE__);
|
||||
} else if (0 == strncmp(cAtStr, "+ADDR=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+NAME=EC_%s\r\n", (cAtStr + 6));
|
||||
printf("ADDR:%s\r\n", cAtStr + 6);
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
memset(cmd_str, 0, sizeof(cmd_str));
|
||||
sprintf(cmd_str, "AT+LENAME=EC_%s\r\n", (cAtStr + 6));
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
g_cp_bt_mac_ready = true;
|
||||
memcpy(g_cp_bt_mac, (cAtStr + 6), 12);
|
||||
} else if (0 == strncmp(cAtStr, "+VER", 4)) {
|
||||
char* cmd = "AT+ADDR\r\n";
|
||||
console_send_atcmd(cmd, strlen(cmd));//get mac addr
|
||||
} else if (0 == strncmp(cAtStr, "+NAME=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+LEADDR\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get LE addr
|
||||
} else if (0 == strncmp(cAtStr, "+LEADDR=", 6)) {
|
||||
char hexMacAddr[6] = {0};
|
||||
char m_tmp_buf[64] = {0};
|
||||
string2hex(&cAtStr[8], 12, hexMacAddr, sizeof(hexMacAddr));
|
||||
sprintf(m_tmp_buf, "AT+ADVDATA=%s\r\n", hexMacAddr);
|
||||
console_send_atcmd(m_tmp_buf, 19);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSENT=", 10)) {
|
||||
return;
|
||||
} else if (0 == strncmp(cAtStr, "+IAPSTAT=3", 10)) {
|
||||
carplay_start();
|
||||
}
|
||||
}
|
||||
|
||||
int iap_data_write(unsigned char *data, int len)
|
||||
{
|
||||
uint8_t *at_str = NULL, *at_str_ptr = NULL;
|
||||
uint8_t *at_prefix = "AT+IAPSEND=";
|
||||
int prefix_len = strlen((char *)at_prefix);
|
||||
int cmd_len = (len * 2 + prefix_len + 2);
|
||||
|
||||
at_str = (uint8_t *)pvPortMalloc(cmd_len + 1);
|
||||
memset(at_str, 0, cmd_len + 1);
|
||||
if (NULL == at_str)
|
||||
return -1;
|
||||
at_str_ptr = at_str;
|
||||
sprintf((char*)at_str_ptr, "%s", (char*)at_prefix);
|
||||
at_str_ptr += prefix_len;
|
||||
hex2str(data, len, (char *)at_str_ptr);
|
||||
at_str_ptr += (len * 2);
|
||||
*at_str_ptr++ = '\r';
|
||||
*at_str_ptr++ = '\n';
|
||||
console_send_atcmd((char *)at_str, cmd_len);
|
||||
vPortFree(at_str);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static void cp_wifi_event_handler( WIFIEvent_t * xEvent )
|
||||
{
|
||||
WIFIEventType_t xEventType = xEvent->xEventType;
|
||||
|
||||
wps_connect_done = 0;
|
||||
|
||||
if (0) {
|
||||
} else if (eWiFiEventConnected == xEventType) {// meter is sta
|
||||
printf("\r\n The meter is connected to ap \r\n");
|
||||
} else if (eWiFiEventDisconnected == xEventType) {// meter is sta
|
||||
printf("\r\n The meter is disconnected from ap \r\n");
|
||||
} else if (eWiFiEventAPStationConnected == xEventType) {// meter is ap
|
||||
printf("\r\n The meter in AP is connected by sta %s \r\n", xEvent->xInfo.xAPStationConnected.ucMac);
|
||||
} else if (eWiFiEventAPStationDisconnected == xEventType) {// meter is ap
|
||||
printf("\r\n The sta %s is disconnected from the meter \r\n", xEvent->xInfo.xAPStationDisconnected.ucMac);
|
||||
}
|
||||
}
|
||||
|
||||
static BaseType_t cp_wifi_init()
|
||||
{
|
||||
int status;
|
||||
WIFI_Context_init();
|
||||
WIFI_RegisterEvent(eWiFiEventMax, cp_wifi_event_handler);
|
||||
for (;;) {
|
||||
status = mmcsd_wait_sdio_ready((int32_t)portMAX_DELAY);
|
||||
if (status == MMCSD_HOST_PLUGED) {
|
||||
printf("detect sdio device\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bt_set_support_carplay()
|
||||
{
|
||||
char cmd_str[64] = {0};
|
||||
|
||||
sprintf(cmd_str, "AT+PROFILE=33962\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));
|
||||
}
|
||||
|
||||
int carlink_cp_bt_wifi_init()
|
||||
{
|
||||
carlink_ey_video_init();
|
||||
cp_wifi_init();
|
||||
console_register_cb(NULL, cp_bt_callback);
|
||||
fsc_bt_main();
|
||||
bt_set_support_carplay();
|
||||
cp_start_wlan();
|
||||
printf("bt wlan init is ok\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -632,7 +632,7 @@ int32_t ec_ble_write(void * data, uint32_t len);
|
||||
int32_t ec_ble_read(void * data, uint32_t len);
|
||||
int32_t ec_ble_open();
|
||||
void ec_ble_close();
|
||||
extern char strQrText[100];
|
||||
extern char strQrText[200];
|
||||
void* initECTiny(void* param)
|
||||
{
|
||||
char uuid[32] = {0};
|
||||
|
@ -3,288 +3,259 @@
|
||||
|
||||
#include "ECTypes.h"
|
||||
|
||||
#define ECSDK_VERSION "1.0.10"
|
||||
#define ECSDK_VERSION "1.0.13.1"
|
||||
|
||||
typedef struct {
|
||||
|
||||
/**
|
||||
* @brief 互联连接状态回调函数
|
||||
* @param status 互联连接状态
|
||||
* @param type 互联连接类型
|
||||
* @note 此函数是非常重要的回调函数。它会返回整个互联的状态。
|
||||
* 有部分互联功能接口,比如:EC_startMirror()/EC_enableDownloadPhoneAppHud()/EC_enableDownloadPhoneAppHud() 等,
|
||||
* 都需要 status为 EC_CONNECT_STATUS_CONNECT_SUCCEED 时,调用才能生效。
|
||||
* 因为这些接口都是在互联成功之后(ECTiny与手机app建立了通讯),才能发指令给手机app,对应功能才能开启。
|
||||
*/
|
||||
void (*onECConnectStatus)(ECConnectedStatus status, ECConnectedType type);
|
||||
|
||||
void (*onMirrorStatus)(ECMirrorStatus status);
|
||||
/**
|
||||
* @brief Called when EasyConnected status changed.
|
||||
*
|
||||
* @param status The changed EasyConnected message.
|
||||
* @brief 投屏状态
|
||||
* @param status 互联投屏状态
|
||||
*/
|
||||
void (*onMirrorStatus)(ECMirrorStatus status);
|
||||
|
||||
/**
|
||||
* @brief 互联状态变更通知
|
||||
* @param status 变更的状态
|
||||
*/
|
||||
void (*onECStatusMessage)(ECStatusMessage status);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down HUD information.
|
||||
*
|
||||
* @param data HUD information.
|
||||
* @brief 手机下发HUD信息时回调
|
||||
* @param data HUD信息
|
||||
*/
|
||||
void (*onPhoneAppHUD)(const ECNavigationHudInfo *data);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down HUD Road Junction Picture.
|
||||
* @brief 手机下发道路引导图时回调
|
||||
* @param data
|
||||
*/
|
||||
void (*onPhoneAppHUDRoadJunctionPicture)(const ECHudRoadJunctionPictureInfo* data);
|
||||
|
||||
/*
|
||||
* @brief Called when phone app tell the music info.
|
||||
*
|
||||
* @param data The information of music.
|
||||
/**
|
||||
* @brief 手机音乐信息变化时回调
|
||||
* @param data
|
||||
*/
|
||||
void (*onPhoneAppMusicInfo)(const ECAppMusicInfo *data);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down some information.
|
||||
*
|
||||
* @param data Buffer of app information.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
* @note data is json string, the fields includes os, osVersion and ip.
|
||||
* Called when ECSDK::openTransport succeed.
|
||||
* @brief 手机下发app信息时回调
|
||||
* @param data app信息
|
||||
* @param length app信息长度
|
||||
* @note data 是json字符串, 包括手机类型、系统版本、ip地址等。
|
||||
* ECTiny 与 手机app建立通讯后会回调此函数
|
||||
*/
|
||||
void (*onPhoneAppInfo)(const void *data, uint32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when ECSDK wants car to do call operations(dial or hang up) via Bluetooth.
|
||||
*
|
||||
* @param type Operation type.
|
||||
*
|
||||
* @param name The person's name of corresponding number.
|
||||
*
|
||||
* @param number Phone numbers.
|
||||
*
|
||||
* @note Phone app is not able to dial or hang up automatically due to the latest system access limitation,
|
||||
* however, car is able to do it via Bluetooth. Therefore, ECSDK moves the call operations
|
||||
* to car, which can dial or hang up when this method is called.
|
||||
* @brief 需要拨打或者挂断蓝牙电话时回调
|
||||
* @param type 操作类型
|
||||
* @param name 电话拨打的姓名
|
||||
* @param number 电话号码
|
||||
* @note 受限于Android/iOS系统的权限,在车机上点击互联投屏的过来的拨打电话,ECTiny无法完成电话的拨打和接听操作,因此需要依赖于车机系统的蓝牙模块完成。
|
||||
* 车机的投屏界面上点击拨打蓝牙电话时,此回调函数会把拨打的用户姓名和电话号码传到车机上,由车机蓝牙模块完成电话的拨打
|
||||
* 1.需要车机端作为蓝牙免提设备(Hand-Free-Device)。
|
||||
* 2.亿连的蓝牙电话功能,需要在车机和手机的HFP保持连接后,才可以正常启用。
|
||||
*/
|
||||
void (*onCallAction)(ECCallType type, const char *name, const char *number);
|
||||
|
||||
/**
|
||||
* @brief Called when bulk data is received.
|
||||
*
|
||||
* @brief 接收手机端发送的数据块
|
||||
* @param data Buffer of bulk data.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
*/
|
||||
void (*onBulkDataReceived)(const void *data, uint32_t length);
|
||||
|
||||
|
||||
/**
|
||||
* @brief onRealMirrorSizeChanged
|
||||
* @param realWidth
|
||||
* @param realHeight
|
||||
*
|
||||
* \note The actual size of the projection screen does not equal the size of the video stream in some cases.
|
||||
* The surrounding area is filled with black. This message calls back the actual size of the projection screen
|
||||
* @brief 投屏状态变更
|
||||
* @param ECVideoInfo 视屏参数
|
||||
* @note 投屏的实际宽高、横竖屏切换时回调此函数
|
||||
*/
|
||||
void (*onMirrorInfoChanged)(const ECVideoInfo *info);
|
||||
|
||||
/**
|
||||
* @brief Called when the license authorization failed. After this interface was called,
|
||||
* all connections would be forced closed.
|
||||
*
|
||||
* @param errCode Error code.
|
||||
*
|
||||
* @param errMsg Error message.
|
||||
* @brief 鉴权失败时回调此函数。ECTiny功能全部不可用
|
||||
* @param errCode 主要用于亿连后台进行排查的错误码,无需关心具体值。
|
||||
* @param errMsg 错误信息。
|
||||
* @note 此回调函数需要处理,当出现激活失败时给与提示。
|
||||
* 该回调一般出现在互联建立过程中,出现时ECTiny会在内部进行释放动作。
|
||||
* ECTiny使用者需要保证合法的激活校验流程,之后重新初始化ECSDK方可使用。
|
||||
*/
|
||||
void (*onLicenseAuthFail)(int32_t errCode, const char *errMsg);
|
||||
|
||||
/**
|
||||
* @brief Called when the license authorization succeed.
|
||||
*
|
||||
* @param code success code. The code can gain specific meaning by ECAuthSuccessCode.
|
||||
*
|
||||
* @param msg success information.
|
||||
*
|
||||
* @param msg the description information.
|
||||
*
|
||||
* @brief 鉴权成时回调此函数
|
||||
* @param code 正常错误码,无需关心具体值。
|
||||
* @param msg 正常激活log信息。
|
||||
* @note 该接口回调一般出现在互联建立过程中,在首次进行激活(手机IME号备案激活)时,回调会包含剩余数量等信息,SDK使用者可根据具体的使用场景进行相关展示。
|
||||
*/
|
||||
void (*onLicenseAuthSuccess)(int32_t code, const char *msg);
|
||||
|
||||
/**
|
||||
* @brief Called when registered command was triggered by VR.
|
||||
*
|
||||
* @param carCmd The triggered command.
|
||||
*
|
||||
* @note Voice control can be implemented with this method by VR.
|
||||
*
|
||||
* @see ECSDK::registerCarCmds
|
||||
* @brief 当注册的控车指令被vr激活时回调
|
||||
* @param carCmd 触发的控车指令
|
||||
* @see EC_registerCarCmds()
|
||||
*/
|
||||
void (*onCarCmdNotified)(const ECCarCmd *carCmd);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app request the HU to start input.
|
||||
*
|
||||
* @param info relevant parameters about the input.
|
||||
* @brief 监听手机端文字输入
|
||||
* @param info 当前需要输入的文字信息,包括输入类型(文字、数字、电话号码等),最大输入长度,默认的文字,最大行数,以及Enter键默认的显示效果及动作。
|
||||
* @note 监听手机端输入法的开始输入状态,并传递此次输入文字的相关信息。
|
||||
*/
|
||||
void (*onInputStart)(const ECInputInfo *info);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app request the HU to cancel input.
|
||||
* @note 监听手机端输入法的结束或者取消的状态,此时车机端键盘也需要取消。
|
||||
*/
|
||||
void (*onInputCancel)();
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the selection of input.
|
||||
* @brief 监听手机端输入光标位置、选择状态信息
|
||||
* @param start 光标开始的位置
|
||||
* @param stop 光标结束的位置
|
||||
* @note 监听手机端输入文字的选择状态,光标状态,车机端并做状态展示。仅对安卓手机有效,苹果手机互联无此回调。
|
||||
*/
|
||||
void (*onInputSelection)(int32_t start, int32_t stop);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the text of input.
|
||||
* @brief 同步当前手机端的文字信息到车机
|
||||
* @param text 当前手机端输入的文字信息。
|
||||
* @note 如在手机端也对输入框内的文字进行输入,需要同步至车机端,保持车机端和手机端的状态同步。
|
||||
*/
|
||||
void (*onInputText)(const char *text);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app send the text of VR or TTS.
|
||||
* @brief 对识别内容进行展示
|
||||
* @param info 手机端语音引擎识别后的文字内容信息。
|
||||
*/
|
||||
void (*onVRTextReceived)(const ECVRTextInfo *info);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the page list.
|
||||
*
|
||||
* @param pages Array of the struct ECPageInfo.
|
||||
*
|
||||
* @param length The length of the array.
|
||||
* @brief 获取快捷方式列表信息
|
||||
* @param pages 返回快捷方式的数组,参考 ECTypes.h 的 ECPageInfo 定义,主要包含图标的编号、名称、icon的唯一标识信息;
|
||||
* @param length pages数组长度;
|
||||
* @note ECPageInfo::page 字段标识了每一个快捷方式的唯一标识,通过该标识,可以实现两个主要的功能:
|
||||
* 1. 通过page编号,可以通过调用 ECSDK::queryPageIcon 获取快捷方式的图标资源。
|
||||
* 2. 通过page编号,可以通过调用 ECSDK::openAppPage 实现快捷打开对应指定手机APP页面
|
||||
*/
|
||||
void (*onPageListReceived)(const ECPageInfo *pages, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the icons.
|
||||
*
|
||||
* @param icons Array of the struct ECIconInfo.
|
||||
*
|
||||
* @param length The length of the array.
|
||||
* @brief 手机app回调图标信息
|
||||
* @param icons 返回快捷方式图标资源的数组,参考 ECTypes.h 的 ECIconInfo 定义,主要包含icon的编号、icon的格式、icon图像数据、icon的数据长度;
|
||||
* @param length icons的数组长度。
|
||||
*/
|
||||
void (*onPageIconReceived)(const ECIconInfo *icons, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell weather.
|
||||
*
|
||||
* @param data Buffer of weather information.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
* @note data pointed to a json string buffer.
|
||||
* @brief 回调天气信息
|
||||
* @param data 天气信息字符串
|
||||
* @param length 字符串长度
|
||||
* @note data 是一个固定格式的json字符串
|
||||
*/
|
||||
void (*onWeatherReceived)(const char *data, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell vr tips.
|
||||
*
|
||||
* @param data Buffer of tips information.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
* @note data pointed to a json string buffer.
|
||||
* @brief 请求VR提醒文字
|
||||
* @param data VR文字
|
||||
* @param length data长度
|
||||
* @note data是一个json字符串
|
||||
* 在使用车机端本地语音助手时,一般需要有一些常驻提示类的使用帮助,这些文字主要通过手机端传输至车机端,由车机端系统完成展示。
|
||||
*/
|
||||
void (*onVRTipsReceived)(const char *data, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when the app requests networking
|
||||
*
|
||||
* @param clientInfo Mobile phone related information
|
||||
*
|
||||
* @note
|
||||
* @brief 手机app发送到车机的请求组网
|
||||
* @param clientInfo 手机app的相关信息
|
||||
* @note 此回调用于BLE组网
|
||||
*/
|
||||
void (*onRequestBuildNet)(const ECBTClientInfo *clientInfo);
|
||||
|
||||
/**
|
||||
* @brief Called when canceling networking
|
||||
*
|
||||
* @note
|
||||
* @brief 手机app取消组网时回调
|
||||
* @note 此回调用于BLE组网
|
||||
*/
|
||||
void (*onRequestBuildNetCancel)();
|
||||
|
||||
/**
|
||||
* @brief Called when networking is completed
|
||||
*
|
||||
* @note
|
||||
* @brief 手机app组网完成时回调
|
||||
* @note 此回调用于BLE组网
|
||||
*/
|
||||
void (*onPhoneBuildNetFinish)();
|
||||
void (*onPhoneBuildNetFinish)(const char* ip);
|
||||
|
||||
/**
|
||||
* @brief Called when app sends AP information
|
||||
*
|
||||
* @param netDeviceInfo AP information
|
||||
*
|
||||
* @note
|
||||
* @brief 手机app通知车机,手机创建的ap信息
|
||||
* @param netDeviceInfo AP信息
|
||||
* @note 此回调用于BLE组网
|
||||
*/
|
||||
void (*onPhoneAPInfo)(const ECBTNetInfo* netDeviceInfo);
|
||||
|
||||
/**
|
||||
* @brief Called when mobile phone has a notification message.
|
||||
* @param notification
|
||||
* @brief 收到手机消息通知时回调
|
||||
* @param notification 消息通知
|
||||
* @note 允许下发手机消息通知功能开启后,当收到短信、微信等消息时,此函数会回调消息到车机
|
||||
* @see EC_requestPhoneNotification()
|
||||
*/
|
||||
void (*onPhoneNotification)(const ECPhoneNotification* notification);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down HUD lane guidance Picture.
|
||||
* @param notification
|
||||
* @brief HUD道路引导图
|
||||
* @param notification 引导图信息
|
||||
* @note 下发HUD导航功能开启后,导航时,有道路引导图时,此函数会回调
|
||||
* @see EC_enableDownloadPhoneAppHud()
|
||||
*/
|
||||
void (*onPhoneAppHUDLaneGuidancePicture)(const ECHudLaneGuidancePictureInfo * data);
|
||||
|
||||
/**
|
||||
* @brief Called when checkOTAUpdate was called, it will tell the result of checkOTAUpdate.
|
||||
*
|
||||
* @param downloadableSoftwares It pointer to a array of ECOTAUpdateSoftware, which is downloadable software.
|
||||
*
|
||||
* @param downloadableLength The length of the downloadable array, if downloadableLength < 0, means check occur error, downloadableLength is error value of ECOTAUpdateErrorCode.
|
||||
*
|
||||
* @param downloadedSoftwares It pointer to a array of ECOTAUpdateSoftware, which is downloaded software.
|
||||
*
|
||||
* @param downloadedLength The length of the downloaded array.
|
||||
* @brief 检测更新函数 EC_checkOTAUpdate()调用后, 此回调函数返回结果
|
||||
* @param downloadableSoftwares 可下载的软件包数组
|
||||
* @param downloadableLength 可下载的软件包数组大小, 如果 downloadableLength < 0 标识出现错误, 错误码参考:ECOTAUpdateErrorCode.
|
||||
* @param downloadedSoftwares 已下载的软件包数组
|
||||
* @param downloadedLength 已下载的软件包数组大小
|
||||
*/
|
||||
void (*onOTAUpdateCheckResult)(const ECOTAUpdateSoftware* downloadableSoftwares, const int32_t downloadableLength, const ECOTAUpdateSoftware* downloadedSoftwares, const uint32_t downloadedLength);
|
||||
|
||||
/**
|
||||
* @brief Called when remote downloadable software has been downloaded to phone.
|
||||
*
|
||||
* @param downloadableSoftwares It pointer to a array of ECOTAUpdateSoftware, which has been in phone, can be downloaded from phone to HU.
|
||||
*
|
||||
* @param downloadableLength The length of the downloadable array.
|
||||
* @brief 有软件包请求下载手机时回调
|
||||
* @param downloadableSoftwares 可下载的软件包数组
|
||||
* @param downloadableLength 可下载软件包数组大小
|
||||
* @note 软件包已存在手机,请求下载到车机
|
||||
*/
|
||||
void (*onOTAUpdateRequestDownload)(const ECOTAUpdateSoftware* downloadableSoftwares, const uint32_t downloadableLength);
|
||||
|
||||
/**
|
||||
* @brief Called when startOTAUpdate is called, it will notify the progress of downloading.
|
||||
*
|
||||
* @param downloadingSoftwareId The id of the downloading software.
|
||||
*
|
||||
* @param progress The progress of the downloading software,which is a percentage.
|
||||
*
|
||||
* @param softwareLeftTime The left time of the downloading software.
|
||||
*
|
||||
* @param otaLeftTime The left time of all the specified software by startOTAUpdate.
|
||||
* @brief EC_startOTAUpdate()调用之后, 此回调函数会回调下载进度
|
||||
* @param downloadingSoftwareId 下载的软件ID
|
||||
* @param progress 下载的进度
|
||||
* @param softwareLeftTime 剩余下载时间
|
||||
* @param otaLeftTime OTA剩余时间
|
||||
*/
|
||||
void (*onOTAUpdateProgress)(const char* downloadingSoftwareId, float progress, uint32_t softwareLeftTime, uint32_t otaLeftTime);
|
||||
|
||||
/**
|
||||
* @brief Called when startOTAUpdate is called, it will notify software is downloaded.
|
||||
*
|
||||
* @param downloadedSoftwareId The id of the downloaded software.
|
||||
*
|
||||
* @param md5Path The md5 file path.
|
||||
*
|
||||
* @param packagePath The software path.
|
||||
*
|
||||
* @param iconPath The icon path.
|
||||
*
|
||||
* @param leftSoftwareNum The amount of software remaining to be downloaded.
|
||||
* @brief EC_startOTAUpdate()调用之后, 下载完成时回调此函数
|
||||
* @param downloadedSoftwareId 下载的软件ID
|
||||
* @param md5Path md5文件路径
|
||||
* @param packagePath 升级包路径
|
||||
* @param iconPath 图标路径
|
||||
* @param leftSoftwareNum 剩余下载数量
|
||||
*/
|
||||
void (*onOTAUpdateCompleted)(const char* downloadedSoftwareId, const char* md5Path, const char* packagePath, const char* iconPath, uint32_t leftSoftwareNum);
|
||||
|
||||
/**
|
||||
* @brief Called when checkOTAUpdate or startOTAUpdate failed.
|
||||
*
|
||||
* @param errCode error code, see ECOTAUpdateErrorCode.
|
||||
*
|
||||
* @param softwarId the id of software.
|
||||
* @brief EC_checkOTAUpdate() 或者 EC_startOTAUpdate() 调用过程出错回调此函数
|
||||
* @param errCode 错误码, 参考:ECOTAUpdateErrorCode.
|
||||
* @param softwarId 软件id
|
||||
*/
|
||||
void (*onOTAUpdateError)(int32_t errCode, const char* softwareId);
|
||||
|
||||
@ -350,67 +321,502 @@ ECConfigHandle EC_createECConfig();
|
||||
void EC_destroyECConfig(ECConfigHandle config);
|
||||
void EC_setBaseConfig(ECConfigHandle config,const char *uuid, const char *version,const char *writableDir);
|
||||
void EC_setCommonConfig(ECConfigHandle config, const char *cfgName, const char *value);
|
||||
/**
|
||||
* @brief 设置 ECTiny 连接的app版本
|
||||
* @param type 0:国内版; 1:海外版
|
||||
*/
|
||||
void EC_setLinkPhoneApp(ECConfigHandle config,int32_t type);
|
||||
void EC_setCommonConfig1(ECConfigHandle config, const char *cfgName, int32_t value);
|
||||
// This function must be called after the EC_start() function.
|
||||
int32_t EC_resetECConfig(const char* config);
|
||||
|
||||
/**
|
||||
* @brief ECTiny 初始化函数
|
||||
* @param config 项目配置
|
||||
* @param listener 回调接口
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此接口为互联必调用的接口。
|
||||
* 1.除了调用 EC_setBaseConfig() 设置基本的运行配置之外,config 一般不需要额外配置。
|
||||
* 2.listener 的生命周期大于 ECTiny 生命周期。即 listener 在 EC_initialize() 调用前就需要初始化,EC_release()之后才可以释放。
|
||||
*/
|
||||
int32_t EC_initialize(ECConfigHandle config, IECCallBack *listener);
|
||||
|
||||
/**
|
||||
* @brief ECTiny 释放函数
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此函数调用后,后面声明的函数调用都会失效。
|
||||
* 没有互联时,ECTiny线程处于block或者waiting状态,占用系统资源不多,所以ECTiny的一般使用场景不需要调用此函数。
|
||||
*/
|
||||
int32_t EC_release();
|
||||
|
||||
/**
|
||||
* @brief 设置ECTiny日志
|
||||
* @param level 日志级别。调试时设置成:EC_LOG_LEVEL_ALL,生产时设置成:EC_LOG_LEVEL_ERROR或者其他高级别
|
||||
* @param type 日志输出类型,设置成 EC_LOG_OUT_STD标准输出。其余类型暂不支持。
|
||||
* @param logDirectory 日志保存位置,暂不支持
|
||||
* @param module 日志模块,通常设置成:EC_LOG_MODULE_SDK | EC_LOG_MODULE_APP
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此接口为互联必调用的接口。
|
||||
*/
|
||||
int32_t EC_setLogInfo(const ECLogLevel level,const ECLogOutputType type,const char *logDirectory, int32_t module);
|
||||
|
||||
/**
|
||||
* @return 获取 ECTiny 版本号
|
||||
*/
|
||||
const char* EC_getVersion();
|
||||
|
||||
/**
|
||||
* @return 获取 ECTiny 升级版本号
|
||||
*/
|
||||
int32_t EC_getVersionCode();
|
||||
|
||||
/**
|
||||
* @brief 开启互联服务
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此接口为互联必调用的接口。
|
||||
*/
|
||||
int32_t EC_start();
|
||||
|
||||
/**
|
||||
* @brief 停止互联服务
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 没有投屏的情况下, ECTiny线程出于阻塞状态,占用的系统资源很少。
|
||||
* 一般使用场景,调用 EC_start() 之后,不需要调用 EC_stop()。
|
||||
*/
|
||||
int32_t EC_stop();
|
||||
|
||||
/**
|
||||
* @brief 绑定文件读写设备
|
||||
* @param handle 文件操作接口
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 对于某些 RTOS 系统,没有标准的文件操作接口,因此需要实现此接口,把基本文件操作的接口传给 ECTiny。
|
||||
* ECTiny会使用此接口读写license和OTA。
|
||||
*/
|
||||
int32_t EC_bindAccessFile(IECAccessFile *handle);
|
||||
|
||||
/**
|
||||
* @brief 绑定usb设备
|
||||
* @param type 互联类型
|
||||
* @param dev usb设备操作接口
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 绑定usb设备读写操作,用于实现usb互联。
|
||||
* @see EC_unbindDevice()
|
||||
*/
|
||||
int32_t EC_bindUSBDevice(ECTransportType type, IECAccessDevice *dev);
|
||||
|
||||
/**
|
||||
* @brief 绑定wifi互联ip
|
||||
* @param type 互联类型
|
||||
* @param ip 对端ip地址
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此函数调用之后, ECTiny会直接连接ip,进行互联。
|
||||
* @see EC_unbindDevice()
|
||||
*/
|
||||
int32_t EC_bindWIFIDevice(ECTransportType type, const char *ip);
|
||||
|
||||
/**
|
||||
* @brief 释放绑定的设备
|
||||
* @param type 互联类型
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此函数与 EC_bindUSBDevice(),EC_bindWIFIDevice(),有绑定与解绑定关系。
|
||||
*/
|
||||
int32_t EC_unbindDevice(ECTransportType type);
|
||||
|
||||
/**
|
||||
* @brief 绑定HID设备
|
||||
* @param dev HID设备
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @see EC_unBindHidDevice()
|
||||
*/
|
||||
int32_t EC_bindHidDevice(IECHidAccessDev* dev);
|
||||
|
||||
/**
|
||||
* @brief 解除HID设备绑定
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @see EC_bindHidDevice()
|
||||
*/
|
||||
int32_t EC_unBindHidDevice();
|
||||
|
||||
/**
|
||||
* @brief 绑定蓝牙ble设备操作接口
|
||||
* @param ioHandle 蓝牙ble设备操作接口
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此接口用于BLE组网方式的互联。
|
||||
* @see EC_unBindBTDevice()
|
||||
*/
|
||||
int32_t EC_bindBTDevice( IECAccessDevice* ioHandle);
|
||||
|
||||
/**
|
||||
* @brief 蓝牙ble设备解绑定
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @see EC_bindBTDevice()
|
||||
*/
|
||||
int32_t EC_unBindBTDevice();
|
||||
|
||||
/**
|
||||
* @brief 设置投屏参数
|
||||
* @param mirrorCfg 投屏参数
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此接口为互联必执行的接口。
|
||||
*/
|
||||
int32_t EC_setMirrorConfig(const ECMirrorConfig *mirrorCfg);
|
||||
|
||||
/**
|
||||
* @brief 设置解码显示设备
|
||||
* @param video 解码显示器
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 解码显示器 IECVideoPlayer 通过此接口注册给 ECTiny之后,由 ECTiny主动调用解码器的开始和停止。
|
||||
*/
|
||||
int32_t EC_setVideoPlayer(IECVideoPlayer* video);
|
||||
|
||||
/**
|
||||
* @brief 设置音频播放器
|
||||
* @param audio 音频播放器
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 声音数据走usb或者wifi时才需要设置此接口。一般项目声音都是走蓝牙a2dp,不需要设置此接口。
|
||||
*/
|
||||
int32_t EC_setAudioPlayer(IECAudioPlayer* audio);
|
||||
|
||||
/**
|
||||
* @brief 设置录音设备
|
||||
* @param audioRecorde 录音设备
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 需要手机app回声降噪的项目才需要设置此接口。
|
||||
*/
|
||||
int32_t EC_setAudioRecorder(IECAudioRecorder* audioRecorde);
|
||||
|
||||
/**
|
||||
* @brief 仪表wifi状态通知接口
|
||||
* @param action 仪表wifi模式:ap/sta。 目前此值不做要求,填写此枚举任意值即可
|
||||
* @param netInfo 网络状态。ECNetWorkInfo::state 必须填写,其余字段不需要填。
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 仪表/车机wifi发生变化时,通过此接口通知给 ECTiny。wifi连接,此接口必调用
|
||||
*/
|
||||
int32_t EC_notifyWifiStateChanged(ECWifiStateAction action, const ECNetWorkInfo* netInfo);
|
||||
|
||||
/**
|
||||
* @brief 请求组网接口
|
||||
* @param phoneID 手机id
|
||||
* @param rly 组网信息
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 只有BLE组网的连接方式,才用到此接口。
|
||||
*/
|
||||
int32_t EC_setRequestBuildNetRly(const char *phoneID, const ECBTRequestBuildNetRly *rly);
|
||||
|
||||
/**
|
||||
* @brief 仪表ip地址上报给手机
|
||||
* @param info 仪表网络信息
|
||||
* @param num 仪表网络信息数量
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 只有BLE组网的连接方式,才用到此接口。
|
||||
*/
|
||||
int32_t EC_setNetInterfaceInfo(const ECNetInterfaceInfo *info,const int32_t num);
|
||||
|
||||
/**
|
||||
* @brief 开始投屏
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此接口为互联必执行的接口。
|
||||
* 此接口调用后,手机app会把 H264 数据发送给 ECTiny。 ECTiny会自动调用 IECVideoPlayer 解码器解码显示。
|
||||
* onECConnectStatus 回调函数,status==EC_CONNECT_STATUS_CONNECT_SUCCEED 时才可以调用此接口,否则无效。
|
||||
* @see EC_stopMirror()
|
||||
*/
|
||||
int32_t EC_startMirror();
|
||||
|
||||
/**
|
||||
* @brief 停止投屏
|
||||
* @note 此接口为互联必执行的接口。
|
||||
* @see EC_startMirror()
|
||||
*/
|
||||
void EC_stopMirror();
|
||||
|
||||
/**
|
||||
* @brief 暂停/开启 投屏
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 目前不调用。调用 EC_startMirror()/EC_stopMirror()
|
||||
*/
|
||||
int32_t EC_pauseMirror();
|
||||
int32_t EC_resumeMirror();
|
||||
int32_t EC_sendTouchEvent(const ECTouchEventData *touch, ECTouchEventType type);
|
||||
int32_t EC_sendBtnEvent(int32_t btnCode, int32_t type);
|
||||
int32_t EC_stopPhoneNavigation();
|
||||
int32_t EC_stopPhoneVR();
|
||||
int32_t EC_uploadNightModeStatus(uint32_t isNightModeOn);
|
||||
int32_t EC_uploadDrivingStatus(ECDrivingStatus status);
|
||||
int32_t EC_enableDownloadPhoneAppAudio(uint32_t supportType, uint32_t autoChangeToBT);
|
||||
void EC_disableDownloadPhoneAppAudio();
|
||||
int32_t EC_enableDownloadPhoneAppHud(uint32_t supportFunction);
|
||||
void EC_disableDownloadPhoneAppHud();
|
||||
int32_t EC_setConnectedBTAddress(const char *carBtMac, const char *phoneBtMac);
|
||||
int32_t EC_sendCarBluetooth(const char *name, const char *adddress, const char *pin);
|
||||
int32_t EC_openAppPage(int32_t page);
|
||||
int32_t EC_queryGPS(uint32_t* status, ECGPSInfo* gps);
|
||||
int32_t EC_queryTime(uint64_t *gmtTime, uint64_t *localTime, char *timeZone, uint32_t len, char* dateTime, uint32_t dateTimeLen);
|
||||
int32_t EC_sendCarStatus(ECCarStatusType carStatus, ECCarStatusValue value);
|
||||
int32_t EC_registerCarCmds(const ECCarCmd *carCmds, uint32_t length);
|
||||
int32_t EC_playCarTTS(const char *text, uint32_t level);
|
||||
int32_t EC_registerSimilarSoundingWords(const char *data, uint32_t length);
|
||||
int32_t EC_sendInputText(const char* text);
|
||||
int32_t EC_sendInputAction(int32_t actionId, int32_t keyCode);
|
||||
int32_t EC_sendInputSelection(int32_t start, int32_t stop);
|
||||
int32_t EC_queryPageList();
|
||||
int32_t EC_queryPageIcon(int32_t* pages, int32_t length);
|
||||
int32_t EC_queryWeather();
|
||||
int32_t EC_queryVRTips();
|
||||
const char* EC_generateQRCodeUrl(ECQRInfo* info);
|
||||
int32_t EC_requestPhoneNotification(int32_t enable);
|
||||
|
||||
/**
|
||||
* @brief 发送触控消息
|
||||
* @param touch 触控数据
|
||||
* @param type 触控类型
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 发送仪表/车机屏幕的触控消息给手机app,互联程序会映射到手机的坐标,让手机app做出响应。
|
||||
*/
|
||||
int32_t EC_sendTouchEvent(const ECTouchEventData *touch, ECTouchEventType type);
|
||||
|
||||
/**
|
||||
* @brief 发送按键消息
|
||||
* @param btnCode 按键键值,取值于:ECBtnCode
|
||||
* @param type 按键类型,取值与:ECBtnEventType
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 发送按键消息给手机app,让手机作出响应。
|
||||
*/
|
||||
int32_t EC_sendBtnEvent(int32_t btnCode, int32_t type);
|
||||
|
||||
/**
|
||||
* @brief 结束手机导航
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
*/
|
||||
int32_t EC_stopPhoneNavigation();
|
||||
|
||||
/**
|
||||
* @brief 结束手机vr语音
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
*/
|
||||
int32_t EC_stopPhoneVR();
|
||||
|
||||
/**
|
||||
* @brief 上传汽车的夜间模式信息到手机
|
||||
* @param isNightModeOn 1:夜间模式; 0: 非夜间模式
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 手机app的显示模式设置为自动时,此接口才能让手机app响应
|
||||
*/
|
||||
int32_t EC_uploadNightModeStatus(uint32_t isNightModeOn);
|
||||
|
||||
/**
|
||||
* @brief 上传汽车的驾驶信息到手机
|
||||
* @param status 驾驶状态
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
*/
|
||||
int32_t EC_uploadDrivingStatus(ECDrivingStatus status);
|
||||
|
||||
/**
|
||||
* @brief 允许手机下发声音数据到仪表/车机
|
||||
* @param supportType 下载的声音类型,取值于 ECAudioType 类型,可以通过或运算下载多种声音
|
||||
* @param autoChangeToBT 是否启用蓝牙优先的策略,当蓝牙连接后,声音自动走蓝牙通道。
|
||||
* 也可通过该接口控制手机端蓝牙连接提示框的弹出,当该参数设置为false后,手机端不再弹出连接蓝牙提示框。
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 只有在连接层成功建立后,接口调用才能成功。参考 onECConnectStatus()
|
||||
* 该接口调用之后,手机app才会下传相应声音,停止音频下传接口为EC_disableDownloadPhoneAppAudio()
|
||||
*/
|
||||
int32_t EC_enableDownloadPhoneAppAudio(uint32_t supportType, uint32_t autoChangeToBT);
|
||||
|
||||
/**
|
||||
* @brief 停止手机下发声音数据
|
||||
*/
|
||||
void EC_disableDownloadPhoneAppAudio();
|
||||
|
||||
/**
|
||||
* @brief 允许手机下发HUD导航信息
|
||||
* @param supportFunction hud导航功能,取值于 ECAPPHUDSupportFunction 类型,可以通过或运算开启多种hud功能
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 只有在连接层成功建立后,接口调用才能成功。参考 onECConnectStatus()
|
||||
* 此接口调用一次即可生效
|
||||
*/
|
||||
int32_t EC_enableDownloadPhoneAppHud(uint32_t supportFunction);
|
||||
|
||||
/**
|
||||
* @brief 停止手机下发HUD导航信息
|
||||
*/
|
||||
void EC_disableDownloadPhoneAppHud();
|
||||
|
||||
/**
|
||||
* @brief 设置连接的蓝牙
|
||||
* @param carBtMac 车机自己的蓝牙地址
|
||||
* @param phoneBtMac 车机连接的蓝牙Mac地址
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此接口的目的是用于对比手机和车机两者连接的蓝牙是不是对方。受限于手机系统限制,无法取得手机的蓝牙物理地址,目前此接口功能已经失效。
|
||||
*/
|
||||
int32_t EC_setConnectedBTAddress(const char *carBtMac, const char *phoneBtMac);
|
||||
|
||||
/**
|
||||
* @brief 发送车机的蓝牙信息给手机
|
||||
* @param name 蓝牙名称
|
||||
* @param adddress 蓝牙地址
|
||||
* @param pin 蓝牙pin码
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
*/
|
||||
int32_t EC_sendCarBluetooth(const char *name, const char *adddress, const char *pin);
|
||||
|
||||
/**
|
||||
* @brief 打开手机界面
|
||||
* @param page 快速访问手机APP的相关界面或功能,如导航、音乐、对讲等,具体取值参考:ECAppPage
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 该接口主要用于如下场景,譬如车机端系统桌面集成快捷按钮,可直达互联的指定页面。
|
||||
*/
|
||||
int32_t EC_openAppPage(int32_t page);
|
||||
|
||||
/**
|
||||
* @brief 查询GPS信息
|
||||
* @param status 当前的请求结果是否有效,0:无效;其余值有效
|
||||
* @param gps GPS信息
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 该接口主要用于车机需要使用到手机端GPS的场景,请求网络当前位置。
|
||||
*/
|
||||
int32_t EC_queryGPS(uint32_t* status, ECGPSInfo* gps);
|
||||
|
||||
/**
|
||||
* @brief 查询手机时间
|
||||
* @param gmtTime 返回GMT(UTC)时间,单位毫秒。
|
||||
* @param localTime 返回当前时区的时间,单位毫秒
|
||||
* @param timeZone 返回当前的时区的字符串。
|
||||
* @param len 当前时区字符串的长度
|
||||
* @param dateTime 返回手机app当前时间字符串
|
||||
* @param dateTimeLen 手机app当前时间字符串长度
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 由于GMT时间涉及到系统函数和时区的计算,建议直接使用后两个参数获取当前时间字符串,然后解析字符串获取到时间
|
||||
*/
|
||||
int32_t EC_queryTime(uint64_t *gmtTime, uint64_t *localTime, char *timeZone, uint32_t len, char* dateTime, uint32_t dateTimeLen);
|
||||
|
||||
/**
|
||||
* @brief 同步车机状态到手机
|
||||
* @param carStatus 车机状态类型
|
||||
* @param value 部分status需要携带状态值
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 部分场景下,需要将车机的部分状态信息通知到手机APP,手机APP需要根据状态做互联的相关逻辑处理。
|
||||
* 如手机APP可根据行车状态,在不同的地区做不同的使用限制。该接口主要用于行车模式功能等功能。
|
||||
*/
|
||||
int32_t EC_sendCarStatus(ECCarStatusType carStatus, ECCarStatusValue value);
|
||||
|
||||
/**
|
||||
* @brief 注册控车指令
|
||||
* @param carCmds 控车指令
|
||||
* .type : 指令类型,是一个全局指令或是一个和页面绑定的指令,见枚举 ECCarCmdEFFECTType 。
|
||||
* .id : 指令id,每个需要识别的指令,都有一个唯一的标识。
|
||||
* .cmd : 期望语音识别的指令,当时一个全局指令时,可以是正则表达式;如"(打开|开启)空调",等价于"打开空调" ,"开启空调";而当是一个和页面绑定的指令词,不支持正则表达式,仅支持明确的指令,如"放大地图"。
|
||||
* .vrText : 当前成功匹配的语义,仅用于当 IECCallback::onCarCmdNotified 回调时,可根据匹配的内容处理相关的动作。
|
||||
* .pauseMusic : 该参数仅用于 ECSDK::registerCarCmds ,告知手机如果触发语音识别时,是否需要暂停当前正在播放的音乐。
|
||||
* .responser : 语音指令执行的结果是由车机端播报,还是由手机端播报。0 车机端播报,1,手机端播报。
|
||||
* .thresholdLevel : 可选项,默认值为0,由手机端指定默认的门限值, 范围参考值 1~9999,识别门限值,值越大识别率越低,误唤醒率越低,开发者在使用语音识别功能时,可在项目中调试设置合适的值。该参数仅在 type= EC_CAR_CMD_TYPE_EFFECTIVE_PAGE 生效;
|
||||
* @param length 注册的指令列表的长度。
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 当发起语音识别后,通过手机端的VR引擎识别后,会转化后具体的指令,通过回调接口 IECCallback::onCarCmdNotified 响应,须在此进行相关处理。
|
||||
*/
|
||||
int32_t EC_registerCarCmds(const ECCarCmd *carCmds, uint32_t length);
|
||||
|
||||
/**
|
||||
* @brief 播放指定的文字
|
||||
* @param text 文字信息
|
||||
* @param level 优先级,0~10,优先级越高,被播放的优先级也越高。
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 与手机的通讯建立成功后,把需要播报的文字传输至手机APP。
|
||||
* 如果车机端配置了 ECSDK::enableDownloadPhoneAppAudio 通过车机端播放手机APP音频,此时音频将以TTS类型,通过USB/wifi传输车机端。
|
||||
*/
|
||||
int32_t EC_playCarTTS(const char *text, uint32_t level);
|
||||
|
||||
/**
|
||||
* @brief 注册近似指令
|
||||
* @param data 需要注册的近音词组,数据格式为JSON格式字符串
|
||||
* {
|
||||
* words:
|
||||
* [
|
||||
* ["词1", ..., "词m"], ///< 数据类型为string数组,近音词集合,数组中的第一个词为显示词。
|
||||
* ...
|
||||
* ["词a", ..., "词n"] ///< 数据类型为string数组,近音词集合,数组中的第一个词为显示词。
|
||||
* ]
|
||||
* }
|
||||
* @param length 注册的指令Json字符串的长度。
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 该接口主要是对 EC_registerCarCmds() 接口的补充,常见使用场景提高语音控车指令的准确度,如“上身车窗”、“上升车窗”可以正确的被识别为同一个含义。
|
||||
*/
|
||||
int32_t EC_registerSimilarSoundingWords(const char *data, uint32_t length);
|
||||
|
||||
/**
|
||||
* @brief 发送给手机端当前已输入的文字
|
||||
* @param text 当前输入的车机端文字
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 此函数用于车机键盘输入功能
|
||||
*/
|
||||
int32_t EC_sendInputText(const char* text);
|
||||
|
||||
/**
|
||||
* @brief 发送给手机端键盘按键事件
|
||||
* @param actionId 当前输入的动作
|
||||
* @param keyCode 键值
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 如车机端输入法点击Enter键,此时需把事件发送给手机端。所有keycode及ActionId对安卓手机都有效;
|
||||
* 苹果手机仅响应actionid=0 keycode=4,苹果手机处理为隐藏手机端输入法,并把输入状态置为inActive状态。
|
||||
* 此函数用于车机键盘输入功能
|
||||
*/
|
||||
int32_t EC_sendInputAction(int32_t actionId, int32_t keyCode);
|
||||
|
||||
/**
|
||||
* @brief 发送给手机端当前光标位置及选中状态
|
||||
* @param start 光标开始的位置。
|
||||
* @param stop 光标结束的位置。
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 如果车机端的光标产生变化,需把对应状态发送至手机端同步。仅对安卓手机有效,苹果手机互联无此回调。
|
||||
* 此函数用于车机键盘输入功能
|
||||
*/
|
||||
int32_t EC_sendInputSelection(int32_t start, int32_t stop);
|
||||
|
||||
/**
|
||||
* @brief 获取快捷方式列表信息
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note ECTiny与手机app传输建立之后。通过 IECCallback::onPageListReceived 回调接口完快捷方式列表信息的接收。
|
||||
*/
|
||||
int32_t EC_queryPageList();
|
||||
|
||||
/**
|
||||
* @brief 获取快捷方式图标资源
|
||||
* @param pages 待请求的page编号的数组,通过 EC_queryPageList 获取。
|
||||
* @param length page编号的数组长度。
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note ECTiny与手机app传输建立之后。通过 IECCallback::onPageIconReceived 回调接口完快捷方式图标资源的的接收。
|
||||
* 为了避免重复的请求,占用带宽资源,以及做到车机端的快捷方式快速显示;车机端系统需要做好缓存策略,对icon的资源信息做到增量更新:
|
||||
* 通过每次互联后 EC_queryPageList 获取最新的列表信息,然后比对车机端缓存的列表信息,仅对增量的资源进行请求更新;
|
||||
*/
|
||||
int32_t EC_queryPageIcon(int32_t* pages, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief 查询天气
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 查询结果通过 IECCallback::onWeatherReceived 回调函数返回
|
||||
*/
|
||||
int32_t EC_queryWeather();
|
||||
|
||||
/**
|
||||
* @brief 车机端语音提醒轮播
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 在使用车机端本地语音助手时,一般需要有一些常驻提示类的使用帮助,这些文字主要通过手机端传输至车机端,由车机端系统完成展示。
|
||||
*/
|
||||
int32_t EC_queryVRTips();
|
||||
|
||||
/**
|
||||
* @brief 生成二维码url
|
||||
* @param info 二维码信息
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
*/
|
||||
const char* EC_generateQRCodeUrl(ECQRInfo* info);
|
||||
|
||||
/**
|
||||
* @brief 允许手机下发手机消息
|
||||
* @param enable 0:禁止; 1:允许
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
*/
|
||||
int32_t EC_requestPhoneNotification(uint32_t enable);
|
||||
|
||||
/**
|
||||
* @brief 检测OTA升级
|
||||
* @param cfg ota配置
|
||||
* @param language 语言
|
||||
* @param mode ota升级模式
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
*/
|
||||
int32_t EC_checkOTAUpdate(const ECOTAConfig* cfg, const ECLanguage language, const ECOTAUpdateCheckMode mode);
|
||||
|
||||
/**
|
||||
* @brief 开始OTA升级
|
||||
* @param softwareIds 需要升级的软件id
|
||||
* @param softwareNum 需要升级的软件id数量
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
*/
|
||||
int32_t EC_startOTAUpdate(const char** softwareIds, const int32_t softwareNum);
|
||||
|
||||
/**
|
||||
* @brief 停止OTA升级
|
||||
*/
|
||||
void EC_stopOTAUpdate();
|
||||
|
||||
/**
|
||||
* @brief 开启iperf服务端
|
||||
* @param ip
|
||||
* @param port
|
||||
* @return
|
||||
* @note 简单实现的iperf功能。车机/仪表进行iperf测试时,建议使用标准iperf
|
||||
*/
|
||||
int32_t EC_startIperfTcpServer(const char* ip, int port);
|
||||
void EC_stopIperfTcpServer();
|
||||
#endif
|
||||
|
@ -194,6 +194,18 @@ enum ECProjectFlavor
|
||||
};
|
||||
typedef enum ECProjectFlavor ECProjectFlavor;
|
||||
|
||||
/**
|
||||
* @enum ECAuthCheckMode
|
||||
*
|
||||
*/
|
||||
enum ECAuthCheckMode {
|
||||
EC_AUTH_CHECK_DEFAULT = 0, ///< default check auth on phone
|
||||
EC_AUTH_CHECK_ON_CAR_NETWORK = 1, ///< check auth on car network
|
||||
EC_AUTH_CHECK_SCAN_CODE_TO_ACTIVATE_FOR_SUDING = 2, ///< scan the code to activate the certificate for suding
|
||||
EC_AUTH_CHECK_SCAN_CODE_TO_ACTIVATE = 4, ///< scan the code to activate the certificate
|
||||
};
|
||||
typedef enum ECAuthCheckMode ECAuthCheckMode;
|
||||
|
||||
/**
|
||||
* @struct ECAuthentication
|
||||
*
|
||||
@ -205,7 +217,7 @@ struct ECAuthentication
|
||||
char pwd[1024]; ///< the specific password for authentication powered by Carbit.
|
||||
char versionName[1024]; ///< the version name of EasyConn.
|
||||
uint32_t versionCode; ///< the version code of EasyConn.
|
||||
uint32_t autoAuthViaCar; ///< specify whether make automatic authentication via car's network.
|
||||
uint32_t authCheckMode; ///< the value of auth check model refer to ECAuthCheckMode.
|
||||
ECProjectFlavor flavor; ///< specify the HU Project market for sale,SDK will carry a flavor by default.see enum ECProjectFlavor in ECTypes.h
|
||||
char reserve[256]; ///< reserve
|
||||
};
|
||||
@ -373,11 +385,22 @@ struct ECOptions
|
||||
ECMirrorMode mirrorMode; ///< tell the app of connected phone which mirror mode would be used.
|
||||
uint32_t bluetoothPolicy; ///< the policy of A2DP message phone sent to the car.
|
||||
uint32_t disableShowCallInfo; ///< true:Don't show call info
|
||||
uint32_t disablePageInRVMap; ///< Block display of some page
|
||||
uint32_t socketTimeoutPeriod; ///< socket timeout period in seconds
|
||||
char reserve[256]; ///< reserve
|
||||
};
|
||||
typedef struct ECOptions ECOptions;
|
||||
|
||||
/**
|
||||
* @enum ECDisablePageInRVMap
|
||||
*
|
||||
*/
|
||||
enum ECDisablePageInRVMap {
|
||||
EC_DISABLE_PAGEINRVMAP_CALLPHONE = 0x0001, ///< Block call display
|
||||
EC_DISABLE_PAGEINRVMAP_MUSIC = 0x0002, ///< Block music display
|
||||
EC_DISABLE_PAGEINRVMAP_MESSAGE = 0x0004, ///< Block message display
|
||||
};
|
||||
|
||||
/**
|
||||
* @enum ECTransportType
|
||||
*
|
||||
|
1332
app/carlink/EC/src/__carlink_ec.c
Normal file
@ -2,5 +2,7 @@
|
||||
#define _CARLINK_EC_H_
|
||||
|
||||
int carlink_ec_init(int argc,char ** argv);
|
||||
void carlink_ec_enable(int enable);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -29,9 +29,12 @@
|
||||
#include "wifi_conf.h"
|
||||
#include "carlink_common.h"
|
||||
|
||||
#define DEV_NAME_PREFIX "AP630_CARLINK"
|
||||
|
||||
static char g_cp_bt_mac[13] = {0};
|
||||
static bool g_cp_bt_mac_ready = false;
|
||||
|
||||
static uint8_t carlink_p2p_name[64] = {0};
|
||||
static uint8_t carlink_ap_ssid[64] = {"ap63011"};
|
||||
static uint8_t carlink_ap_passwd[16] = {"88888888"};
|
||||
static uint8_t carlink_wifi_mac[32] = {0};
|
||||
@ -65,6 +68,17 @@ extern err_t dhcp_server_start(struct netif *netif, ip4_addr_t *start, ip4_addr_
|
||||
extern err_t wlan_ethernetif_init(struct netif *netif);
|
||||
#define lwip_ipv4_addr(addr) ((addr[0]) | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24))
|
||||
|
||||
const char *carlink_get_bt_mac()
|
||||
{
|
||||
if (!g_cp_bt_mac_ready)
|
||||
return NULL;
|
||||
return (const char *)g_cp_bt_mac;
|
||||
}
|
||||
|
||||
const char *carlink_get_wifi_p2p_name()
|
||||
{
|
||||
return (const char *)carlink_p2p_name;
|
||||
}
|
||||
|
||||
const char *carlink_get_wifi_ssid()
|
||||
{
|
||||
@ -74,7 +88,7 @@ const char *carlink_get_wifi_ssid()
|
||||
|
||||
const char *carlink_get_wifi_mac()
|
||||
{
|
||||
wifi_get_mac_address(carlink_wifi_mac);
|
||||
wifi_get_mac_address((char *)carlink_wifi_mac);
|
||||
return (const char *)carlink_wifi_mac;
|
||||
}
|
||||
|
||||
@ -173,7 +187,11 @@ static void carlink_start_wlan()
|
||||
}
|
||||
memcpy(ap_prefix, g_cp_bt_mac + 8, 4);
|
||||
carlink_reset_wifi_ap_info(ap_prefix);
|
||||
#if (CARLINK_EC)
|
||||
start_p2p((const char *)carlink_p2p_name, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd);
|
||||
#else
|
||||
start_ap(36, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd, 1);
|
||||
#endif
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
@ -194,18 +212,113 @@ static void carlink_start_wlan()
|
||||
dhcp_server_start(&gnetif[0], &dhcp_addr_start, &dhcp_addr_end);
|
||||
|
||||
|
||||
netif_set_up(&gnetif[0]);
|
||||
//netif_set_up(&gnetif[0]);
|
||||
lwiperf_start_tcp_server_default(carlink_lwiperf_report_cb_impl, NULL);
|
||||
lwip_tcpip_init_done_flag = 1;
|
||||
carlink_carplay_add_vendor_ie();
|
||||
}
|
||||
|
||||
void cp_wlan_start(void){
|
||||
netif_set_up(&gnetif[0]);
|
||||
}
|
||||
|
||||
static void dump_ip_addr(const char *msg, const ip_addr_t *server_addr)
|
||||
{
|
||||
printf("%s %d.%d.%d.%d \r\n", msg,
|
||||
ip4_addr1_16(ip_2_ip4(server_addr)), ip4_addr2_16(ip_2_ip4(server_addr)), ip4_addr3_16(ip_2_ip4(server_addr)), ip4_addr4_16(ip_2_ip4(server_addr)));
|
||||
}
|
||||
|
||||
|
||||
static void dhcp_client_status_callback(struct netif *netif, int status, const ip_addr_t *server_addr)
|
||||
{
|
||||
if (&gnetif[0] == netif) {
|
||||
dump_ip_addr("dhcp server ip :", (const ip_addr_t *)server_addr);
|
||||
dump_ip_addr("dhcp client ip :", (const ip_addr_t *)&netif->ip_addr);
|
||||
dump_ip_addr("dhcp client netmask:", (const ip_addr_t *)&netif->netmask);
|
||||
dump_ip_addr("dhcp client gw :", (const ip_addr_t *)&netif->gw);
|
||||
}
|
||||
}
|
||||
|
||||
int start_sta_ext(const char* ssid, const char* passwd, char need_passwd)
|
||||
{
|
||||
int ret = -1;
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
|
||||
ret = start_sta(ssid, passwd, need_passwd);
|
||||
if (ret != 0) {
|
||||
printf("start wifi sta failed\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (lwip_tcpip_init_done_flag) {
|
||||
netif_remove(&gnetif[0]);
|
||||
netif_add(&gnetif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, wlan_ethernetif_init, tcpip_input);
|
||||
netif_set_default(&gnetif[0]);
|
||||
dhcp_regisger_status_callback(dhcp_client_status_callback);
|
||||
netif_set_up(&gnetif[0]);
|
||||
dhcp_start(&gnetif[0]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __restart_p2p(const char *dev_name, const char *ssid, const char *passwd)
|
||||
{
|
||||
int ret = -1;
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
gw.addr = lwip_ipv4_addr(ucGatewayAddress);
|
||||
|
||||
ret = start_p2p(dev_name, ssid, passwd);
|
||||
if (ret != 0) {
|
||||
printf("restart wifi p2p failed\r\n");
|
||||
return ret;
|
||||
}
|
||||
if (!lwip_tcpip_init_done_flag) {
|
||||
printf("lwip tcpip is not inited\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dhcp_stop(&gnetif[0]);
|
||||
netif_remove(&gnetif[0]);
|
||||
|
||||
netif_add(&gnetif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, wlan_ethernetif_init, tcpip_input);
|
||||
|
||||
netif_set_up(&gnetif[0]);
|
||||
ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int restart_p2p()
|
||||
{
|
||||
if (!g_cp_bt_mac_ready) {
|
||||
printf("bt is not ready at %s", __func__);
|
||||
return -1;
|
||||
}
|
||||
return __restart_p2p((const char *)carlink_p2p_name, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd);
|
||||
}
|
||||
|
||||
static void carlink_reset_wifi_ap_info(const char *prefex)
|
||||
{
|
||||
if (prefex) {
|
||||
memset(carlink_ap_ssid, 0, sizeof(carlink_ap_ssid));
|
||||
sprintf((char *)carlink_ap_ssid, "AP630_CARLINK_%s", prefex);
|
||||
sprintf((char *)carlink_ap_ssid, "%s_%s", DEV_NAME_PREFIX, prefex);
|
||||
memset(carlink_p2p_name, 0, sizeof(carlink_p2p_name));
|
||||
sprintf((char *)carlink_p2p_name, "DIRECT-%s_p2p_%s", DEV_NAME_PREFIX, prefex);//do not delete "DIRECT-" !!!
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,11 +369,11 @@ static void carlink_bt_callback(char * cAtStr)
|
||||
carlink_notify_event(&ev);
|
||||
} else if (0 == strncmp(cAtStr, "+ADDR=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+NAME=AP630_CARLINK_%s\r\n", (cAtStr + 6 + 8));
|
||||
sprintf(cmd_str, "AT+NAME=%s_%s\r\n", DEV_NAME_PREFIX, (cAtStr + 6 + 8));
|
||||
printf("ADDR:%s\r\n", cAtStr + 6);
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
memset(cmd_str, 0, sizeof(cmd_str));
|
||||
sprintf(cmd_str, "AT+LENAME=AP630_CARLINK_%s\r\n", (cAtStr + 6 + 8));
|
||||
sprintf(cmd_str, "AT+LENAME=%s_%s\r\n", DEV_NAME_PREFIX, (cAtStr + 6 + 8));
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
memcpy(g_cp_bt_mac, (cAtStr + 6), 12);
|
||||
carlink_carplay_ie_replace_bt_mac(cAtStr + 6, 12);
|
||||
@ -396,7 +509,7 @@ static void carlink_wifi_event_handler( WIFIEvent_t * xEvent )
|
||||
char *mac = NULL;
|
||||
|
||||
if (xEvent) {
|
||||
mac = xEvent->xInfo.xAPStationConnected.ucMac;
|
||||
mac = (char *)xEvent->xInfo.xAPStationConnected.ucMac;
|
||||
sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
}
|
||||
|
||||
@ -414,6 +527,40 @@ static void carlink_wifi_event_handler( WIFIEvent_t * xEvent )
|
||||
}
|
||||
}
|
||||
|
||||
#if ( ipconfigUSE_DHCP_HOOK != 0 )
|
||||
eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase,
|
||||
uint32_t ulIPAddress )
|
||||
{
|
||||
eDHCPCallbackAnswer_t eReturn;
|
||||
char g_ip_str[32] = {0};
|
||||
|
||||
sprintf(g_ip_str, "%d.%d.%d.%d\r\n", (ulIPAddress >> 0) & 0xFF,
|
||||
(ulIPAddress >> 8) & 0xFF, (ulIPAddress >> 16) & 0xFF, (ulIPAddress >> 24) & 0xFF);
|
||||
printf("\r\n eDHCPPhase:%d ulIPAddress:%s state:%d \r\n", eDHCPPhase, g_ip_str, getDhcpClientState());
|
||||
if (getDhcpClientState() == 0)
|
||||
return eDHCPStopNoChanges;
|
||||
|
||||
switch( eDHCPPhase )
|
||||
{
|
||||
case eDHCPPhaseFinished:
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
case eDHCPPhasePreDiscover :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
|
||||
case eDHCPPhasePreRequest :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
default :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
}
|
||||
|
||||
return eReturn;
|
||||
}
|
||||
#endif
|
||||
|
||||
static BaseType_t carlink_wifi_init()
|
||||
{
|
||||
int status;
|
||||
|
@ -25,6 +25,7 @@ static pthread_mutex_t carlink_com_locker =
|
||||
.xAttr = { .iType = 0 }
|
||||
};
|
||||
|
||||
void pthread_key_system_init();
|
||||
|
||||
void carlink_rfcomm_data_read_hook(void* buf, int len)
|
||||
{
|
||||
@ -41,7 +42,7 @@ void carlink_rfcomm_data_read_hook(void* buf, int len)
|
||||
|
||||
void carlink_notify_event(struct carlink_event *ev)
|
||||
{
|
||||
if (-1 != ev->type && NULL != carlink_event_queue) {
|
||||
if (CARLINK_EVENT_NONE != ev->type && NULL != carlink_event_queue) {
|
||||
xQueueSend(carlink_event_queue, ev, 0);
|
||||
}
|
||||
}
|
||||
|
@ -16,13 +16,14 @@ typedef enum
|
||||
CARLINK_ANDROID_AUTO = 5,
|
||||
CARLINK_ECLINK = 0x06,
|
||||
CARLINK_CARPLAY_WIRELESS,
|
||||
CARLINK_AUTO_WIRELESS
|
||||
CARLINK_AUTO_WIRELESS,
|
||||
CARLINK_ECLINK_WIRELESS,
|
||||
}CARLink_TYPE;
|
||||
|
||||
|
||||
|
||||
#define CARLINK_VIDEO_WIDTH 800
|
||||
#define CARLINK_VIDEO_HEIGHT 480
|
||||
#define CARLINK_VIDEO_HEIGHT 380
|
||||
|
||||
|
||||
|
||||
@ -72,6 +73,8 @@ int carlink_wlan_tcp_ip_is_ready();
|
||||
void carlink_bt_open();
|
||||
void carlink_bt_close();
|
||||
void carlink_restart_bt_wifi();
|
||||
const char *carlink_get_bt_mac();
|
||||
const char *carlink_get_wifi_p2p_name();
|
||||
const char *carlink_get_wifi_ssid();
|
||||
const char *carlink_get_wifi_passwd();
|
||||
const char *carlink_get_wifi_mac();
|
||||
|
@ -25,6 +25,15 @@ static int g_disp_x = 0, g_disp_y = 0, g_disp_width = LCD_WIDTH, g_disp_height =
|
||||
static int g_video_width = LCD_WIDTH, g_video_height = LCD_HEIGHT, g_video_fps = 30;
|
||||
static int g_hide_carlink_flag = 0;
|
||||
|
||||
static int g_active_video_x = 0, g_active_video_y = 0;
|
||||
|
||||
void set_carlink_active_video_info(int x, int y)//for android auto
|
||||
{
|
||||
g_active_video_x = x;
|
||||
g_active_video_y = y;
|
||||
}
|
||||
|
||||
|
||||
void set_carlink_video_info(int w, int h, int fps)
|
||||
{
|
||||
g_video_width = w;
|
||||
@ -145,7 +154,7 @@ void set_h264_frame_free(video_frame_s* frame)
|
||||
}
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
}
|
||||
|
||||
uint8_t map_flag = 0;
|
||||
static void h264_decode_proc(void *pvParameters)
|
||||
{
|
||||
MFCHandle *handle = NULL;
|
||||
@ -197,6 +206,11 @@ static void h264_decode_proc(void *pvParameters)
|
||||
}
|
||||
|
||||
if (g_hide_carlink_flag == 0) {
|
||||
if(map_flag)
|
||||
map_flag = 0;
|
||||
printf("Exit navigation =========\r\n ");
|
||||
Set_sys_wifi(0);
|
||||
//printf("start carplay or andrord auto .\r\n");
|
||||
ark_lcd_osd_enable(LCD_VIDEO_LAYER, 0);
|
||||
ark_lcd_osd_enable(LCD_UI_LAYER, 1);
|
||||
}
|
||||
@ -236,15 +250,16 @@ static void h264_decode_proc(void *pvParameters)
|
||||
//continue;
|
||||
|
||||
for(i = 0; i < outBuf.num; i++) {
|
||||
int active_offset = 0;
|
||||
align_width = outBuf.frameWidth;
|
||||
align_height = outBuf.frameHeight;
|
||||
|
||||
if(!(align_width && align_height))
|
||||
continue;
|
||||
|
||||
yaddr = outBuf.buffer[i].yBusAddress;
|
||||
uaddr = yaddr + align_width * align_height;
|
||||
vaddr = yaddr + align_width * align_height * 5/4;
|
||||
active_offset = g_active_video_y * align_width;
|
||||
yaddr = outBuf.buffer[i].yBusAddress + active_offset + g_active_video_x;
|
||||
uaddr = outBuf.buffer[i].yBusAddress + align_width * align_height + active_offset / 2 + g_active_video_x;
|
||||
vaddr = 0;//yaddr + align_width * align_height * 5/4;
|
||||
|
||||
if (carlink_lcd_take == 0) {
|
||||
carlink_lcd_take = 1;
|
||||
@ -295,6 +310,8 @@ static void h264_decode_proc(void *pvParameters)
|
||||
info.y = g_disp_y;
|
||||
info.width = g_disp_width;
|
||||
info.height = g_disp_height;
|
||||
if (g_active_video_x != 0)
|
||||
info.stride = outBuf.frameWidth;
|
||||
|
||||
if (info.format == LCD_OSD_FORAMT_YUV420)
|
||||
ark_lcd_set_osd_yuv420_mode(LCD_VIDEO_LAYER, LCD_OSD_Y_UV420);
|
||||
@ -306,7 +323,8 @@ static void h264_decode_proc(void *pvParameters)
|
||||
ark_lcd_set_osd_info_atomic(LCD_VIDEO_LAYER, &info);
|
||||
ark_lcd_osd_enable(LCD_VIDEO_LAYER, 1);
|
||||
ark_lcd_set_osd_sync(LCD_VIDEO_LAYER);
|
||||
ark_lcd_osd_enable(LCD_UI_LAYER, 0);
|
||||
Set_sys_wifi(1);
|
||||
// ark_lcd_osd_enable(LCD_UI_LAYER, 0);
|
||||
ark_lcd_set_osd_sync(LCD_UI_LAYER);
|
||||
vVideoDisplayBufRender(dstaddr);
|
||||
if (outBuf.num > 1) {// for apple h264
|
||||
@ -317,6 +335,13 @@ static void h264_decode_proc(void *pvParameters)
|
||||
if (delta_ts > 0)
|
||||
vTaskDelay(pdMS_TO_TICKS(delta_ts));
|
||||
}
|
||||
if(!map_flag){
|
||||
// printf("###############################################.\r\n");
|
||||
request_UI("maps:");
|
||||
map_flag = 1;
|
||||
// printf("###############################################.\r\n");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//printf("all use:%d ms dec:%ld ms all ts:%ld ms\r\n", (get_timer(0) - ts) / 1000, dec_ts, (get_timer(0) - all_ts) / 1000);
|
||||
|
@ -29,7 +29,7 @@ int get_carlink_video_fps(void);
|
||||
void set_carlink_video_info(int w, int h, int fps);//set h264 video stream info from phone
|
||||
void set_carlink_display_info(int x, int y, int w, int h);//set carlink show area in lcd
|
||||
void set_carlink_display_state(int on); // on: 1.display carlink; 0. display native ui
|
||||
|
||||
void set_carlink_active_video_info(int x, int y);//for android auto
|
||||
|
||||
#define WRITE_BE32(ptr, val) \
|
||||
do { \
|
||||
|
@ -580,6 +580,33 @@ static void usb_read_thread(void *para)
|
||||
status = usb_wait_stor_dev_pluged(portMAX_DELAY);
|
||||
if (status == USB_DEV_PLUGED) {
|
||||
printf("usb dev inserted.\n");
|
||||
FF_FILE *fp = ff_fopen("/usb/update.bin", "rb");
|
||||
if (fp) {
|
||||
UpFileHeader header;
|
||||
SysInfo *sysinfo = GetSysInfo();
|
||||
if (ff_fread(&header, 1, sizeof(header), fp) == sizeof(header)) {
|
||||
if (header.magic != MKTAG('U', 'P', 'D', 'F')) {
|
||||
printf("Wrong update file, don't update.\n");
|
||||
} else {
|
||||
if (header.checksum != sysinfo->app_checksum) {
|
||||
printf("found different update file(0x%x-0x%x), update...\n",
|
||||
header.checksum, sysinfo->app_checksum);
|
||||
sysinfo->update_media_type = UPDATE_MEDIA_USB;
|
||||
sysinfo->update_status = UPDATE_STATUS_START;
|
||||
SaveSysInfo();
|
||||
hub_usb_dev_reset();
|
||||
vTaskDelay(500);
|
||||
wdt_cpu_reboot();
|
||||
} else {
|
||||
printf("the update file version is same, don't update.\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
ff_fclose(fp);
|
||||
} else {
|
||||
printf("open update.bin fail.\n");
|
||||
}
|
||||
/*printf("usb dev inserted.\n");
|
||||
#ifdef OTA_UPDATE_SUPPORT
|
||||
FF_FILE *fp = ff_fopen("/usb/update.bin", "rb");
|
||||
if (fp) {
|
||||
@ -635,7 +662,7 @@ static void usb_read_thread(void *para)
|
||||
} else {
|
||||
printf("open update.bin fail.\n");
|
||||
}
|
||||
#endif
|
||||
#endif*/
|
||||
} else if (status == USB_DEV_UNPLUGED) {
|
||||
printf("usb removed.\n");
|
||||
}
|
||||
@ -710,7 +737,7 @@ void awtk_thread(void *data)
|
||||
|
||||
|
||||
/* can demo */
|
||||
//can_demo();
|
||||
can_demo();
|
||||
|
||||
/* read sd card demo */
|
||||
#ifdef SDMMC_SUPPORT
|
||||
@ -785,13 +812,15 @@ void awtk_thread(void *data)
|
||||
extern int gui_app_start(int lcd_w, int lcd_h);
|
||||
gui_app_start (OSD_WIDTH, OSD_HEIGHT);
|
||||
#endif
|
||||
|
||||
// float cell = 0;
|
||||
// static float cell_value = 0;
|
||||
// static uint8_t cell_count = 0;
|
||||
|
||||
while(1) {
|
||||
|
||||
#ifdef TASK_STATUS_MONITOR
|
||||
static uint32_t idletick = 0;
|
||||
uint8_t CPU_RunInfo[1024];
|
||||
|
||||
if (xTaskGetTickCount() - idletick > configTICK_RATE_HZ * 10) {
|
||||
memset(CPU_RunInfo,0,1024);
|
||||
vTaskList((char *)&CPU_RunInfo); //获取任务运行时间信息
|
||||
@ -807,6 +836,25 @@ void awtk_thread(void *data)
|
||||
idletick = xTaskGetTickCount();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*if ((xTaskGetTickCount() - idletick > configTICK_RATE_HZ*3) && (Get_sys_power_on_self_test() == 100)) {
|
||||
adc_light = adc_get_channel_value(ADC_CH_AUX2);//光感
|
||||
adc_voltage = adc_get_channel_value(ADC_CH_AUX3);//电压
|
||||
// DEBUG_PRINT("adc_light = %d ,adc_voltage = %d . ",adc_light,adc_voltage);
|
||||
idletick = xTaskGetTickCount();
|
||||
cell = adc_voltage_calculation();
|
||||
// DEBUG_PRINT("cell %lf .\r\n",cell);
|
||||
// cell_value += cell;
|
||||
// cell_count++;
|
||||
// if(cell_count>=8){
|
||||
// cell_value = cell_value/cell_count;
|
||||
// Set_sys_voltage(cell_value);
|
||||
// cell_value = 0;
|
||||
// cell_count = 0;
|
||||
// }
|
||||
Set_sys_voltage(cell);
|
||||
|
||||
}*/
|
||||
vTaskDelay(pdMS_TO_TICKS(10)); /*Just to let the system breath*/
|
||||
}
|
||||
}
|
||||
|
162
app/moto/protocol/Bt_Interaction_protocol.c
Normal file
@ -0,0 +1,162 @@
|
||||
#include "awtk.h"
|
||||
#include "conversation_protocol.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "chip.h"
|
||||
#include "board.h"
|
||||
#include "serial.h"
|
||||
#include "sysinfo.h"
|
||||
#include "user_data.h"
|
||||
#include "data_port.h"
|
||||
#include "universal.h"
|
||||
|
||||
|
||||
#define MAX_ENTRIES 100 // 假设最大条目数为100
|
||||
|
||||
// 定义电话本条目结构体
|
||||
typedef struct {
|
||||
char name[50];
|
||||
char phone[20];
|
||||
} PhoneBookEntry;
|
||||
|
||||
PhoneBookEntry phoneBook[MAX_ENTRIES]; // 存储电话本信息的数组
|
||||
int numEntries = 0; // 当前电话本条目数量
|
||||
|
||||
void Phone_book_analysis(void){
|
||||
/*int numEntries = 0; // 当前电话本条目数量
|
||||
|
||||
// 模拟收到的电话本信息字符串
|
||||
char data[] = "+PBDATA=1<FF>JACK<FF>12345678911";
|
||||
|
||||
// 解析字符串并提取姓名和电话号码
|
||||
char *token = strtok(data, "<FF>"); // 使用<FF>作为分隔符
|
||||
if (token != NULL) {
|
||||
token = strtok(NULL, "<FF>"); // 跳过第一个分隔符
|
||||
if (token != NULL) {
|
||||
strcpy(phoneBook[numEntries].name, token);
|
||||
token = strtok(NULL, "<FF>");
|
||||
if (token != NULL) {
|
||||
strcpy(phoneBook[numEntries].phone, token);
|
||||
numEntries++;
|
||||
printf("Phone book entry stored successfully.\n");
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// 打印存储的电话本信息
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
printf("Entry %d: Name - %s, Phone - %s\n", i+1, phoneBook[i].name, phoneBook[i].phone);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Call_analysis(){
|
||||
|
||||
}
|
||||
|
||||
void parseBtATCommand(char* cAtCmd,int cATLen) {
|
||||
uint8_t str[64];
|
||||
static uint8_t flag = 0;
|
||||
uint8_t j=0;
|
||||
uint32_t num = 0;
|
||||
|
||||
printf(">>");
|
||||
for(uint16_t i =0;i<cATLen;i++){
|
||||
printf("%c",cAtCmd[i]);
|
||||
}
|
||||
|
||||
if(strlen(cAtCmd) > 8 && !memcmp(cAtCmd,"+A2DPDEV",8))//蓝牙连接设备信息 远端设备信息 蓝牙连接
|
||||
{
|
||||
Set_sys_bt_connect_state(1);
|
||||
}else if(strlen(cAtCmd) > 8 && !memcmp(cAtCmd,"+A2DPDEV",8)){
|
||||
|
||||
}else if(strlen(cAtCmd) > 9 && !memcmp(cAtCmd,"+A2DPLOST",9)){//远距离断开 设备丢失
|
||||
|
||||
}else if(strlen(cAtCmd) > 12 && !memcmp(cAtCmd,"+AVRCPSTAT=1",12)){//AVRCP状态 1是配对状态 蓝牙断开
|
||||
Set_sys_bt_connect_state(0);
|
||||
}else if(strlen(cAtCmd) > 6 && !memcmp(cAtCmd,"+PBCNT",6)){//电话本数量
|
||||
num = atoi(cAtCmd + 7); //从数字的起始位置开始转换为整数
|
||||
printf("Extracted number from command: %d\n", num);
|
||||
}else if(strlen(cAtCmd) > 7 && !memcmp(cAtCmd,"+PBDATA",7)){//电话号码
|
||||
printf("----------------------------\r\n");
|
||||
// 解析字符串并提取姓名和电话号码
|
||||
// char *token = strtok(cAtCmd, "<FF>"); // 使用<FF>作为分隔符
|
||||
/*char *token = strtok(cAtCmd, 0x3F); // 使用<FF>作为分隔符
|
||||
printf("token1 > %s .\r\n",token);
|
||||
if (token != NULL) {
|
||||
// token = strtok(NULL, "<FF>"); // 跳过第一个分隔符
|
||||
token = strtok(NULL, 0x3F); // 跳过第一个分隔符
|
||||
printf("token2 > %s .\r\n",token);
|
||||
if (token != NULL) {
|
||||
strcpy(phoneBook[numEntries].name, token);
|
||||
printf("token3 > %s .\r\n",token);
|
||||
// token = strtok(NULL, "<FF>");
|
||||
token = strtok(NULL, 0x3F); // 跳过第一个分隔符
|
||||
if (token != NULL) {
|
||||
strcpy(phoneBook[numEntries].phone, token);
|
||||
printf("token4 > %s .\r\n",token);
|
||||
numEntries++;
|
||||
printf("Phone book entry stored successfully.\n");
|
||||
}
|
||||
}
|
||||
}*/
|
||||
printf(">>");
|
||||
for(uint16_t i =0;i<cATLen;i++){
|
||||
printf("%02X ",cAtCmd[i]);
|
||||
}
|
||||
|
||||
char call_num[20];
|
||||
char call_name[20];
|
||||
uint16_t len1=0;
|
||||
uint16_t len2=0;
|
||||
for(uint16_t i=0;i<cATLen;i++){
|
||||
if(cAtCmd[i] == 0xFF){
|
||||
if(!len1)
|
||||
len1 = i;
|
||||
else
|
||||
len2 = i;
|
||||
}
|
||||
}
|
||||
printf("len1 = %d,len2 = %d.\r\n",len1,len2);
|
||||
char *start;
|
||||
char *start2;
|
||||
char *start3;
|
||||
char *start4 = cAtCmd + len2 +1;//call number
|
||||
printf("start4 >%s.\r\n",start4);
|
||||
|
||||
strncpy(start2, (cAtCmd + len2), len2);//number
|
||||
printf("start2 >%s.\r\n",start2);
|
||||
strncpy(start, (cAtCmd + 10), len2-len1);//name
|
||||
printf("start >%s, start2 >%s .\r\n",start,start2);
|
||||
|
||||
|
||||
// char *start = cAtCmd + 10;
|
||||
// char *start2;
|
||||
// strncpy(start2, start, len1);
|
||||
// char *start3 = start + len1;
|
||||
|
||||
// // char *end = strchr(start, 0x3F);
|
||||
// // char *end2 = strchr(end, 0x3F);
|
||||
// printf("start >%s, end >%s, end2 >%s .\r\n",start,start2,start3);
|
||||
|
||||
|
||||
|
||||
|
||||
// if (end) {
|
||||
// *end = '\0';
|
||||
// strncpy(call_num, start, 19);
|
||||
// call_num[19] = '\0'; // 确保字符串以null结尾
|
||||
// printf("call_num > %s .\r\n",call_num);
|
||||
// }
|
||||
// if (end2) {
|
||||
// *end2 = '\0';
|
||||
// strncpy(call_name, end, 19);
|
||||
// call_name[19] = '\0'; // 确保字符串以null结尾
|
||||
// printf("call_name > %s .\r\n",call_name);
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
}
|
6
app/moto/protocol/Bt_Interaction_protocol.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef BT_INTERACTION_PROTOCOL_H
|
||||
#define BT_INTERACTION_PROTOCOL_H
|
||||
|
||||
|
||||
|
||||
#endif
|
@ -1,2 +1,69 @@
|
||||
#include "awtk.h"
|
||||
#include "can_protocol.h"
|
||||
|
||||
uint8_t tcs_twinkle = 0;
|
||||
uint8_t tcs_switch = 0;
|
||||
|
||||
//37B
|
||||
void tcsworking_event_handing(int *buf){
|
||||
uint8_t data = 0;
|
||||
*(buf++);
|
||||
*(buf++);
|
||||
data = *(buf++);
|
||||
tcs_twinkle = getBitValue(data,7);//tcs闪烁控制指令 为1闪烁
|
||||
}
|
||||
|
||||
//12B
|
||||
void tcsswitch_event_handing(int *buf){
|
||||
uint8_t data = 0;
|
||||
uint8_t tcs_data = 0;
|
||||
data = *(buf++);
|
||||
tcs_data = getBit2Value(data,0);//tcs开关信号
|
||||
if(tcs_data<=1)
|
||||
tcs_switch = tcs_data;
|
||||
}
|
||||
//101
|
||||
void speed_event_handing(int *buf){
|
||||
uint16_t eng_temp = 0;
|
||||
uint16_t data = 0;
|
||||
double buf_value = 0;
|
||||
*(buf++);
|
||||
*(buf++);
|
||||
*(buf++);
|
||||
*(buf++);
|
||||
|
||||
data = *(buf++) &0xFF;
|
||||
data = (*(buf++)&0xFF) | data<<8;
|
||||
|
||||
buf_value = data; //值为60-120
|
||||
if(buf_value>5280)
|
||||
buf_value = 255;
|
||||
else if(buf_value>2730)
|
||||
buf_value = ((buf_value*0.1)-273);
|
||||
else
|
||||
buf_value = 0;
|
||||
eng_temp = (int)buf_value;
|
||||
Set_sys_can_temp(eng_temp);
|
||||
}
|
||||
|
||||
//0xA5
|
||||
void abs_dtc_event_handing(int *buf){
|
||||
char dtc[5] = {0};
|
||||
dtc[4] = *(buf++)&0xFF;
|
||||
dtc[3] = *(buf++)&0xFF;
|
||||
dtc[2] = *(buf++)&0xFF;
|
||||
dtc[1] = *(buf++)&0xFF;
|
||||
dtc[0] = *(buf++)&0xFF;
|
||||
Get_can_abs_dtc(dtc);
|
||||
}
|
||||
|
||||
//0x402
|
||||
void ecu_dtc_event_handing2(int *buf){
|
||||
char dtc[5] = {0};
|
||||
dtc[4] = *(buf++)&0xFF;
|
||||
dtc[3] = *(buf++)&0xFF;
|
||||
dtc[2] = *(buf++)&0xFF;
|
||||
dtc[1] = *(buf++)&0xFF;
|
||||
dtc[0] = *(buf++)&0xFF;
|
||||
Get_can_abs_dtc(dtc);
|
||||
}
|
@ -70,29 +70,31 @@ void vbat_led_off(void){
|
||||
|
||||
|
||||
void light_gpio_init(void){
|
||||
// //灯光使能
|
||||
// gpio_direction_output(GPIO_LIGHT, TRUE);
|
||||
//灯光使能
|
||||
gpio_direction_output(47, TRUE);
|
||||
//R_LED
|
||||
gpio_direction_output(GPIO_LIGHT_R_LED, TRUE);
|
||||
//YG_LED
|
||||
gpio_direction_output(GPIO_LIGHT_YG_LED, TRUE);
|
||||
//ABS_LED
|
||||
gpio_direction_output(GPIO_LIGHT_ABS, TRUE);
|
||||
//OIL_LED
|
||||
gpio_direction_output(GPIO_LIGHT_OIL, TRUE);
|
||||
//L_LED
|
||||
gpio_direction_output(GPIO_LIGHT_L_LED, TRUE);
|
||||
//N_LED
|
||||
gpio_direction_output(GPIO_LIGHT_N_LED, TRUE);
|
||||
//ENG_LED
|
||||
gpio_direction_output(GPIO_LIGHT_ENG_LED, TRUE);
|
||||
// #if (MOTO_WARE_HOSE == MOTO_ICMX_A580A)
|
||||
// //ABS_LED
|
||||
// gpio_direction_output(GPIO_LIGHT_ABS, TRUE);
|
||||
// //ENG_LED
|
||||
// gpio_direction_output(GPIO_LIGHT_ENG_LED, TRUE);
|
||||
// #endif
|
||||
//VBAT_LED
|
||||
gpio_direction_output(GPIO_LIGHT_VBAT_LED, TRUE);
|
||||
|
||||
gpio_direction_input(GPIO_LIGHT_SET);
|
||||
gpio_direction_input(GPIO_LIGHT_MODE);
|
||||
|
||||
gpio_timer();
|
||||
gpio_timer();//按键 //左右灯光
|
||||
|
||||
}
|
||||
|
||||
@ -101,16 +103,18 @@ void light_off(void){
|
||||
gpio_direction_output(GPIO_LIGHT_R_LED, FALSE);
|
||||
//YG_LED
|
||||
gpio_direction_output(GPIO_LIGHT_YG_LED, FALSE);
|
||||
//ABS_LED
|
||||
gpio_direction_output(GPIO_LIGHT_ABS, FALSE);
|
||||
//OIL_LED
|
||||
gpio_direction_output(GPIO_LIGHT_OIL, FALSE);
|
||||
//L_LED
|
||||
gpio_direction_output(GPIO_LIGHT_L_LED, FALSE);
|
||||
//N_LED
|
||||
gpio_direction_output(GPIO_LIGHT_N_LED, FALSE);
|
||||
//ENG_LED
|
||||
gpio_direction_output(GPIO_LIGHT_ENG_LED, FALSE);
|
||||
// #if (MOTO_WARE_HOSE == MOTO_ICMX_A580A)
|
||||
// //ABS_LED
|
||||
// gpio_direction_output(GPIO_LIGHT_ABS, FALSE);
|
||||
// //ENG_LED
|
||||
// gpio_direction_output(GPIO_LIGHT_ENG_LED, FALSE);
|
||||
// #endif
|
||||
//VBAT_LED
|
||||
gpio_direction_output(GPIO_LIGHT_VBAT_LED, FALSE);
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include "tkc/types_def.h"
|
||||
|
||||
#define GPIO_LIGHT 47
|
||||
|
||||
|
||||
#define GPIO_LIGHT_R_LED_FLAG 11
|
||||
#define GPIO_LIGHT_L_LED_FLAG 10
|
||||
|
@ -10,9 +10,10 @@ KEY_DAT gs_keyDat[KEY_NUMBERS]={0};
|
||||
bool key_readKeyPin(uint8_t keyx)
|
||||
{
|
||||
bool status;
|
||||
if(keyx==0) status = gpio_get_value(GPIO_LIGHT_MODE);
|
||||
else if(keyx==1) status = gpio_get_value(GPIO_LIGHT_SET);
|
||||
return status;
|
||||
if(keyx==0) status = gpio_get_value(GPIO_LIGHT_SET);
|
||||
else if(keyx==1) status = gpio_get_value(GPIO_LIGHT_MODE);
|
||||
// return (!status);//低有效
|
||||
return (status);//高有效
|
||||
}
|
||||
|
||||
void key_Scan(void)
|
||||
@ -28,6 +29,9 @@ void key_Scan(void)
|
||||
}
|
||||
}
|
||||
|
||||
extern uint8_t map_flag;
|
||||
static int step_about = 0;
|
||||
static int step = 0;
|
||||
|
||||
void check_key(void)
|
||||
{
|
||||
@ -44,7 +48,7 @@ void check_key(void)
|
||||
gs_keyDat[1].flag_Reset=1;
|
||||
gs_keyDat[0].keyCnt=0;
|
||||
gs_keyDat[1].keyCnt=0;
|
||||
// printf("set mode key \r\n");
|
||||
// printf("two long key ---------------------\r\n");
|
||||
Key_Distinction(KEY_SHORT_ON,LV_KEY_OTHER1);
|
||||
}
|
||||
else if(gs_keyDat[i].keyCnt==KEY_LONGPRESS_COUNTER)
|
||||
@ -55,14 +59,14 @@ void check_key(void)
|
||||
{
|
||||
gs_keyDat[i].flag_Reset=1;
|
||||
gs_keyDat[i].keyCnt=0;
|
||||
// printf("set key long key\r\n");
|
||||
// printf("LV_KEY_OPTION key long key\r\n");
|
||||
Key_Distinction(KEY_LONG_ON,LV_KEY_OPTION);
|
||||
}
|
||||
if(i==1 && gs_keyDat[0].flag_Pressed==KEY_OFF)
|
||||
{
|
||||
gs_keyDat[i].flag_Reset=1;
|
||||
gs_keyDat[i].keyCnt=0;
|
||||
// printf("mode key long key\r\n");
|
||||
// printf("LV_KEY_SELECT key long key\r\n");
|
||||
Key_Distinction(KEY_LONG_ON,LV_KEY_SELECT);
|
||||
}
|
||||
|
||||
@ -76,12 +80,36 @@ void check_key(void)
|
||||
{
|
||||
if(i==0 && gs_keyDat[1].flag_Pressed==KEY_OFF)
|
||||
{
|
||||
// printf("set key short key\r\n");
|
||||
// printf("LV_KEY_OPTION-------------------------.\r\n");
|
||||
// if(map_flag){
|
||||
// // KnobUpdate(0,0,0,0,0,1);
|
||||
// request_UI("maps:");
|
||||
// }else
|
||||
// if(Get_sys_wifi()){
|
||||
// printf("option DOWN .\r\n");
|
||||
// android_auto_send_key_event(20,1);
|
||||
// android_auto_send_key_event(20,0);
|
||||
// // android_auto_send_knob_event(19,1);
|
||||
// // android_auto_send_knob_event(19,0);
|
||||
// }else
|
||||
Key_Distinction(KEY_SHORT_ON,LV_KEY_OPTION);
|
||||
}
|
||||
else if(i==1 && gs_keyDat[0].flag_Pressed==KEY_OFF)
|
||||
{
|
||||
// printf("mode key short key\r\n");
|
||||
// printf("LV_KEY_SELECT-------------------------.\r\n");
|
||||
// if(map_flag){
|
||||
// // KnobUpdate(0,0,0,0,0,-1);
|
||||
// request_UI("maps:");
|
||||
// }else
|
||||
// if(Get_sys_wifi()){
|
||||
// printf("select ENTER .\r\n");
|
||||
// android_auto_send_key_event(66,1);
|
||||
// android_auto_send_key_event(66,0);
|
||||
// // android_auto_send_key_event(20,1);
|
||||
// // android_auto_send_key_event(20,0);
|
||||
// // android_auto_send_knob_event(20,1);
|
||||
// // android_auto_send_knob_event(20,0);
|
||||
// }else
|
||||
Key_Distinction(KEY_SHORT_ON,LV_KEY_SELECT);
|
||||
}
|
||||
}
|
||||
@ -143,7 +171,7 @@ static void gpio_handler(void *param)
|
||||
int gpio_timer(void){
|
||||
// printf("gpio_timer .\r\n");
|
||||
if (xTaskCreate(gpio_handler, "gpio_handler", configMINIMAL_STACK_SIZE, NULL,
|
||||
configMAX_PRIORITIES / 3, NULL) != pdPASS) {
|
||||
configMAX_PRIORITIES - 5, NULL) != pdPASS) {
|
||||
printf("create uart rx demo task fail.\n");
|
||||
return -1;
|
||||
}
|
||||
|
539
app/moto/protocol/ota_protocol.c
Normal file
@ -0,0 +1,539 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "chip.h"
|
||||
#include "board.h"
|
||||
#include "serial.h"
|
||||
#include "sysinfo.h"
|
||||
#include "conversation_protocol.h"
|
||||
|
||||
#include "sfud.h"
|
||||
|
||||
#include "ota_update.h"
|
||||
#include "updatefile.h"
|
||||
#include "romfile.h"
|
||||
#include "animation.h"
|
||||
#include "ff_stdio.h"
|
||||
|
||||
#include "awtk.h"
|
||||
#include "ota_protocol.h"
|
||||
|
||||
|
||||
int flash_copy_demo(void);
|
||||
|
||||
#if DEVICE_TYPE_SELECT != EMMC_FLASH
|
||||
#include "ff_sfdisk.h"
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
UART_FRAME_START,
|
||||
UART_FRAME_FILEINFO,
|
||||
UART_FRAME_FILEXFER,
|
||||
UART_FRAME_FINISH,
|
||||
} eUartFrameType;
|
||||
|
||||
typedef enum {
|
||||
UUP_STATE_IDLE,
|
||||
UUP_STATE_START,
|
||||
UUP_STATE_GET_FILEINFO,
|
||||
UUP_STATE_FILE_TFR,
|
||||
UUP_STATE_END,
|
||||
} eUartUpdateState;
|
||||
|
||||
#define UUP_ACK_OK 1
|
||||
#define UUP_ACK_FAIL 0
|
||||
|
||||
#define UUP_MAX_FILE_SIZE 0x1000000
|
||||
#define UUP_RX_FRAME_NUM 16
|
||||
#define UUP_MAX_LOADER_SIZE STEPLDR_MAX_SIZE//0x10000
|
||||
|
||||
static int uup_status = UUP_STATE_IDLE;
|
||||
static int uup_file_type = 0;
|
||||
static int uup_file_size = 0;
|
||||
static int uup_packet_num = 0;
|
||||
static int uup_rev_packet = 0;
|
||||
static int uup_rev_len = 0;
|
||||
static char uup_filename[32];
|
||||
static FF_FILE *uup_file = NULL;
|
||||
|
||||
#define UUP_PACKET_SIZE 128
|
||||
#define UUP_MAX_FRAME_LEN (UUP_PACKET_SIZE + 16)
|
||||
#define UUP_PACKET_A27_SIZE 4096
|
||||
#define UUP_MAX_FRAME_A27_LEN (UUP_PACKET_A27_SIZE + 16)
|
||||
#define UUP_RX_FRAME_NUM 16
|
||||
#define BYTESPERPAGE 256
|
||||
#define PAGESPERSECTORS 16
|
||||
#define UUP_BUF_SIZE (BYTESPERPAGE * PAGESPERSECTORS)
|
||||
|
||||
#define IMAGE_RW_SIZE 0x10000
|
||||
#define NEW_APPLDR_CHECKSUM_OFFSET 0x14
|
||||
|
||||
#define AMT630_BIN_OFFSET 0x41000
|
||||
#define BOOTANIM_BIN_OFFSET 0x741000
|
||||
#define ROM_BIN_OFFSET 0xb41000
|
||||
#define NEW_APPFOOSET 0x17F0000
|
||||
#define AMT630_BIN_MAX_SIZE 0x700000
|
||||
|
||||
/*
|
||||
#define AMT630_BIN_OFFSET 0x41000
|
||||
#define BOOTANIM_BIN_OFFSET 0x501000//0x341000
|
||||
#define ROM_BIN_OFFSET 0x801000
|
||||
#define NEW_APPFOOSET 0xb01000
|
||||
#define AMT630_BIN_MAX_SIZE 0x4c0000
|
||||
*/
|
||||
|
||||
static uint32_t uup_app_offset;
|
||||
static uint32_t uup_burn_offset;
|
||||
static unsigned char uup_buf[4096];
|
||||
static unsigned int uup_buf_len = 0;
|
||||
static unsigned int checksum = 0,calc_checksum = 0xffffffff;
|
||||
|
||||
static void uup_send_ack(UartPort_t *uap, int type, int ret)
|
||||
{
|
||||
/*unsigned char buf[7] = {0x55, 0x80, 0xc5, 0x02, 0x00, 0x00, 0x00};
|
||||
int i;
|
||||
buf[4] = type;
|
||||
buf[5] = ret;
|
||||
for (i = 1; i < 6; i++)
|
||||
buf[6] ^= buf[i];
|
||||
iUartWrite(uap, buf, 7, pdMS_TO_TICKS(100));*/
|
||||
unsigned char buf[8] = {0x55, 0x80, 0xc5, 0x02, 0x00, 0x00, 0x00, 0x00};
|
||||
int i;
|
||||
|
||||
buf[5] = type;
|
||||
buf[6] = ret;
|
||||
if(ret == 0){
|
||||
Set_sys_power_on_self_test(100);
|
||||
Set_sys_return_demo(2);
|
||||
Set_sys_plan(0);
|
||||
Set_sys_pace(0);
|
||||
}
|
||||
for (i = 1; i < 7; i++)
|
||||
buf[7] ^= buf[i];
|
||||
// printf("630->uart:");
|
||||
// for(uint8_t j=0;j<8;j++){
|
||||
// printf("%02x ",buf[j]);
|
||||
// }
|
||||
// printf("\n");
|
||||
|
||||
iUartWrite(uap, buf, 8, pdMS_TO_TICKS(100));
|
||||
}
|
||||
|
||||
void uup_ota_update(UartPort_t *uap, uint8_t *framebuf, size_t len)
|
||||
{
|
||||
int frametype = framebuf[0];
|
||||
uint8_t *buf = framebuf + 1;
|
||||
unsigned int framelen;
|
||||
unsigned int packetnum;
|
||||
sfud_flash *sflash = sfud_get_device(0);
|
||||
SysInfo *sysinfo = GetSysInfo();
|
||||
//printf("uup_ota_update frametype =%d \n",frametype);
|
||||
switch (frametype) {
|
||||
case UART_FRAME_START:
|
||||
printf("UART3_Modification_Type .\n");
|
||||
UART3_Modification_Type();
|
||||
vTaskDelay(10);
|
||||
printf("start sfud erase flash .\n");
|
||||
//擦除flash
|
||||
uup_app_offset = NEW_APPFOOSET;
|
||||
uup_burn_offset = uup_app_offset;
|
||||
//uup_send_ack(uap, frametype, UUP_ACK_OK);
|
||||
//Set_sys_power_on_self_test(150);
|
||||
printf("erase add %X , size %X .\r\n",uup_app_offset,AMT630_BIN_MAX_SIZE);
|
||||
if(sfud_erase(sflash, uup_app_offset, AMT630_BIN_MAX_SIZE)==SFUD_SUCCESS){
|
||||
vTaskDelay(100);
|
||||
printf("UART3_Type_regression .\n");
|
||||
UART3_Type_regression();
|
||||
vTaskDelay(100);
|
||||
printf("UART_FRAME_START sfud erase ok.\n");
|
||||
uup_send_ack(uap, frametype, UUP_ACK_OK);
|
||||
}else{
|
||||
vTaskDelay(100);
|
||||
printf("UART3_Type_regression .\n");
|
||||
UART3_Type_regression();
|
||||
vTaskDelay(100);
|
||||
printf("UART_FRAME_START sfud erase fail.\n");
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
|
||||
}
|
||||
uup_status = UUP_STATE_START;
|
||||
break;
|
||||
case UART_FRAME_FILEINFO:
|
||||
if (uup_status != UUP_STATE_START && uup_status != UUP_STATE_GET_FILEINFO) {
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
break;
|
||||
}
|
||||
uup_file_type = buf[0];
|
||||
if (uup_file_type > UPFILE_TYPE_LNCHEMMC) {
|
||||
printf("Rev wrong file type %d.\n", uup_file_type);
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
break;
|
||||
}
|
||||
uup_packet_num = (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
||||
uup_file_size = 128 * uup_packet_num;
|
||||
if (uup_file_size > AMT630_BIN_MAX_SIZE) {
|
||||
printf("Rev wrong file size.\n");
|
||||
printf("uup_file_size = 0x%x ,uup_packet_num = 0x%x .\n",uup_file_size,uup_packet_num);
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
break;
|
||||
}
|
||||
printf("uup_file_size = 0x%x .\n",uup_file_size);
|
||||
uup_packet_num = uup_packet_num/32;
|
||||
|
||||
Set_sys_plan(uup_packet_num);
|
||||
|
||||
uup_rev_packet = 0;
|
||||
uup_send_ack(uap, frametype, UUP_ACK_OK);
|
||||
uup_status = UUP_STATE_GET_FILEINFO;
|
||||
calc_checksum = 0xffffffff;
|
||||
break;
|
||||
case UART_FRAME_FILEXFER:
|
||||
if (uup_status != UUP_STATE_GET_FILEINFO && uup_status != UUP_STATE_FILE_TFR) {
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
break;
|
||||
}
|
||||
|
||||
packetnum = buf[0];
|
||||
if ((uup_rev_packet & 0xff) != packetnum) {
|
||||
printf("Wrong packet number.\n");
|
||||
//printf("buf 0 - 4 : 0x%x ,0x%x ,0x%x ,0x%x ,0x%x \n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
|
||||
//printf("packetnum = 0x%x,uup_rev_packet = 0x%x \n",packetnum,uup_rev_packet);
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
break;
|
||||
}
|
||||
//printf("uup_rev_packet==0 ---------TURE\n");
|
||||
//printf("uup_rev_packet %d.\n", uup_rev_packet);
|
||||
if (uup_rev_packet==0) { //第一条数据保存其crc校验码
|
||||
/*if (uup_file_type == UPFILE_TYPE_WHOLE) {
|
||||
UpFileHeader *header = (UpFileHeader*)&buf[1];
|
||||
if (header->magic != MKTAG('U', 'P', 'D', 'F')) {
|
||||
printf("Wrong whole file magic.\n");
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
break;
|
||||
}
|
||||
checksum = header->checksum;
|
||||
sysinfo->app_size = header->files[0].size;
|
||||
printf("sysinfo->appsize = 0x%x", sysinfo->app_size);
|
||||
}else if (uup_file_type == UPFILE_TYPE_RESOURCE) {
|
||||
RomHeader *header = (RomHeader *)&buf[1];
|
||||
if (header->magic != MKTAG('R', 'O', 'M', 'A')) {
|
||||
printf("Wrong resource file magic.\n");
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
break;
|
||||
}
|
||||
checksum = header->checksum;
|
||||
} else if (uup_file_type == UPFILE_TYPE_ANIMATION) {
|
||||
BANIHEADER *header = (BANIHEADER *)&buf[1];
|
||||
if (header->magic != MKTAG('B', 'A', 'N', 'I')) {
|
||||
printf("Wrong animation file magic.\n");
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
break;
|
||||
}
|
||||
checksum = header->checksum;
|
||||
} else */
|
||||
if (uup_file_type == UPFILE_TYPE_APP) {//代码文件
|
||||
unsigned int magic = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24);
|
||||
if (magic != UPFILE_APP_MAGIC) {
|
||||
printf("Wrong app file magic.\n");
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
break;
|
||||
}
|
||||
unsigned char *tmp = buf + 1 + NEW_APPLDR_CHECKSUM_OFFSET;
|
||||
checksum = tmp[0] | (tmp[1] <<8) | (tmp[2] << 16) | (tmp[3] << 24);
|
||||
}else if (uup_file_type == UPFILE_TYPE_ANIMATION) {//动画文件
|
||||
BANIHEADER *header = (BANIHEADER *)&buf[1];
|
||||
if (header->magic != MKTAG('B', 'A', 'N', 'I')) {
|
||||
printf("Wrong animation file magic.\n");
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
break;
|
||||
}
|
||||
checksum = header->checksum;
|
||||
}else if (uup_file_type == UPFILE_TYPE_RESOURCE) {//资源文件
|
||||
RomHeader *header = (RomHeader *)&buf[1];
|
||||
if (header->magic != MKTAG('R', 'O', 'M', 'A')) {
|
||||
printf("Wrong resource file magic.\n");
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
break;
|
||||
}
|
||||
checksum = header->checksum;
|
||||
}
|
||||
printf(" file_type = %d ,No1.checksum = 0x%x\n",uup_file_type,checksum);
|
||||
}
|
||||
framelen = len - 2;
|
||||
//printf("framelen = %d ,uup_packet_num =%d ,uup_rev_packet = %d \n",framelen,uup_packet_num,uup_rev_packet);
|
||||
/* only last frame size is less than UUP_PACKET_SIZE */
|
||||
if (framelen > UUP_PACKET_A27_SIZE ||
|
||||
(framelen < UUP_PACKET_A27_SIZE && uup_rev_packet != uup_packet_num)) { //UUP_PACKET_A27_SIZE
|
||||
printf("Wrong packet len.\n");
|
||||
printf("uup_rev_packet = %d, uup_packet_num = %d \n",uup_rev_packet,uup_packet_num);
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
break;
|
||||
}
|
||||
memcpy(uup_buf + uup_buf_len, buf+1, framelen);
|
||||
uup_buf_len += framelen;
|
||||
uup_rev_packet++;
|
||||
//uup_send_ack(uap, frametype, UUP_ACK_OK);
|
||||
if (uup_buf_len == UUP_BUF_SIZE) {
|
||||
printf("uup_rev_packet = %d , save_data.\n",uup_rev_packet);
|
||||
uup_send_ack(uap, frametype, UUP_ACK_OK);
|
||||
Set_sys_pace(uup_rev_packet);
|
||||
//printf("addr=0x%x,size=%x\n",uup_burn_offset,framelen);
|
||||
//sfud_erase_write(sflash, uup_burn_offset, UUP_BUF_SIZE, uup_buf);
|
||||
sfud_write(sflash, uup_burn_offset, UUP_BUF_SIZE, uup_buf);
|
||||
if (uup_rev_packet == 1){//UUP_BUF_SIZE/UUP_PACKET_SIZE) {
|
||||
//printf("enter1 uup_rev_packet = %d \n",uup_rev_packet);
|
||||
/*if (uup_file_type == UPFILE_TYPE_WHOLE) {
|
||||
UpFileHeader *pheader = (UpFileHeader *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
} else if (uup_file_type == UPFILE_TYPE_RESOURCE) {
|
||||
RomHeader *pheader = (RomHeader *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
} else if (uup_file_type == UPFILE_TYPE_ANIMATION) {
|
||||
BANIHEADER *pheader = (BANIHEADER *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
} else if (uup_file_type == UPFILE_TYPE_APP) {*/
|
||||
if (uup_file_type == UPFILE_TYPE_APP) {//代码文件
|
||||
unsigned int *tmp = (unsigned int *)(uup_buf + NEW_APPLDR_CHECKSUM_OFFSET);
|
||||
*tmp = 0;
|
||||
}else if (uup_file_type == UPFILE_TYPE_ANIMATION) {//动画文件
|
||||
BANIHEADER *pheader = (BANIHEADER *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
}else if (uup_file_type == UPFILE_TYPE_RESOURCE) {//资源文件
|
||||
RomHeader *pheader = (RomHeader *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
}
|
||||
//}
|
||||
}
|
||||
calc_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, calc_checksum);//计算校验和
|
||||
uup_buf_len =0;
|
||||
uup_burn_offset += UUP_BUF_SIZE;
|
||||
}else if (uup_buf_len > UUP_BUF_SIZE) {
|
||||
printf("loader file is too large.\n");
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
break;
|
||||
}
|
||||
/*memcpy(&uup_sysinfo, &buf[2], sizeof(SysInfo));
|
||||
sfud_erase_write(sflash, uup_burn_offset, framelen, &buf[1]);//128字节写一次
|
||||
uup_burn_offset += framelen;*/
|
||||
uup_status = UUP_STATE_FILE_TFR;
|
||||
break;
|
||||
case UART_FRAME_FINISH:
|
||||
if (uup_status != UUP_STATE_FILE_TFR && uup_status != UART_FRAME_FINISH) {
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
break;
|
||||
}
|
||||
if (!buf[0]) {
|
||||
printf("update end with error!\n");
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
uup_status = UUP_STATE_END;
|
||||
break;
|
||||
}
|
||||
framelen = len - 2;
|
||||
//printf("finish calc_checksum =%x\n",calc_checksum);
|
||||
if(uup_buf_len){//若最后一包数据不为0 则存数据并且继续计算校验和
|
||||
//sfud_erase_write(sflash, uup_burn_offset, uup_buf_len, uup_buf);
|
||||
sfud_write(sflash, uup_burn_offset, uup_buf_len, uup_buf);
|
||||
//若数据为32 即首次的4k 那么将其置为0
|
||||
if (uup_rev_packet <= 1){//< UUP_BUF_SIZE / UUP_PACKET_SIZE) {
|
||||
printf("enter2 uup_rev_packet = %d \n",uup_rev_packet);
|
||||
/*if (uup_file_type == UPFILE_TYPE_WHOLE) {
|
||||
UpFileHeader *pheader = (UpFileHeader *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
} else if (uup_file_type == UPFILE_TYPE_RESOURCE) {
|
||||
RomHeader *pheader = (RomHeader *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
} else if (uup_file_type == UPFILE_TYPE_ANIMATION) {
|
||||
BANIHEADER *pheader = (BANIHEADER *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
} else if (uup_file_type == UPFILE_TYPE_APP) {*/
|
||||
if (uup_file_type == UPFILE_TYPE_APP) {
|
||||
unsigned int *checksum = (unsigned int *)(uup_buf + NEW_APPLDR_CHECKSUM_OFFSET);
|
||||
*checksum = 0;
|
||||
}else if (uup_file_type == UPFILE_TYPE_ANIMATION) {
|
||||
BANIHEADER *pheader = (BANIHEADER *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
}else if (uup_file_type == UPFILE_TYPE_RESOURCE) {
|
||||
RomHeader *pheader = (RomHeader *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
}
|
||||
}
|
||||
printf("enter2 uup_buf_len =%d calc_checksum================0x%x\n",uup_buf_len,calc_checksum);
|
||||
calc_checksum = xcrc32(uup_buf, uup_buf_len, calc_checksum);
|
||||
Set_sys_pace(0);
|
||||
Set_sys_upgrade(1);
|
||||
}
|
||||
|
||||
/*if (calc_checksum != checksum) {
|
||||
printf("checksum error ! ! ! .\r\n");
|
||||
}else{
|
||||
printf("checksum ok .\r\n");
|
||||
}*/
|
||||
|
||||
if (calc_checksum != checksum) {
|
||||
printf("calc_checksum = 0x%02x,checksum = 0x%02x.\n",calc_checksum,checksum);
|
||||
printf("whole crc check after burn fail!\n");
|
||||
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
||||
uup_rev_packet = 0;
|
||||
checksum = 0;
|
||||
calc_checksum = 0xffffffff;
|
||||
uup_buf_len = 0;
|
||||
framelen = 0;
|
||||
break;
|
||||
} else {
|
||||
uup_send_ack(uap, frametype, UUP_ACK_OK);
|
||||
vTaskDelay(1000);
|
||||
UART3_Modification_Type();
|
||||
printf("uap close .\r\n");
|
||||
printf("test amt630h update ok!\n");
|
||||
sysinfo->image_offset=0x40000;
|
||||
sysinfo->reserved[9] = uup_file_type;
|
||||
sysinfo->upgrade_flag=uup_buf_len;
|
||||
sysinfo->upgrade_appsize=uup_file_size;
|
||||
SaveSysInfo();
|
||||
vTaskDelay(500);
|
||||
printf("TaskDelay 500ms SaveSysInfo .\n");
|
||||
flash_copy_demo();
|
||||
wdt_cpu_reboot();
|
||||
}
|
||||
uup_rev_packet = 0;
|
||||
checksum = 0;
|
||||
calc_checksum = 0xffffffff;
|
||||
uup_buf_len = 0;
|
||||
framelen = 0;
|
||||
uup_status = UUP_STATE_END;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int flash_copy_demo(void)
|
||||
{
|
||||
uint32_t calchecksum,appchecksum,imageoff,new_appoffset,new_appsize;
|
||||
int i;
|
||||
uint8_t *buf;
|
||||
sfud_flash *sflash = sfud_get_device(0);
|
||||
|
||||
printf("enter copy flash .\n");
|
||||
|
||||
new_appsize=uup_file_size; //根据串口升级的协议获取
|
||||
new_appoffset = NEW_APPFOOSET; //升级的程序可以固定写在这个地址,预留3M
|
||||
if(uup_file_type == UPFILE_TYPE_APP){
|
||||
imageoff = AMT630_BIN_OFFSET; //固定的 运行区固定地址
|
||||
}else if(uup_file_type == UPFILE_TYPE_ANIMATION){
|
||||
imageoff = BOOTANIM_BIN_OFFSET; //固定的 运行区固定地址
|
||||
}else if(uup_file_type == UPFILE_TYPE_RESOURCE){
|
||||
imageoff = ROM_BIN_OFFSET;
|
||||
}
|
||||
//imageoff = AMT630_BIN_OFFSET; //固定的 运行区固定地址
|
||||
printf("copy flash init ok.\n");
|
||||
|
||||
Set_sys_plan((new_appsize/IMAGE_RW_SIZE)+1);
|
||||
printf("new_appsize = %x ,start flash copy .\n",new_appsize);
|
||||
|
||||
// sfud_qspi_fast_read_enable(sfud_get_device(0), 1);
|
||||
// printf("sfud_qspi_fast_read_enable ok.\n");
|
||||
buf = pvPortMalloc(IMAGE_RW_SIZE);
|
||||
if (!buf) {
|
||||
printf("%s %d malloc %d bytes fail.\n", __FUNCTION__, __LINE__, IMAGE_RW_SIZE);
|
||||
return -1;
|
||||
}
|
||||
printf("start copy flash ok.\n");
|
||||
for(i=0;i<new_appsize/IMAGE_RW_SIZE;i++)
|
||||
{
|
||||
printf("i = %d start read .\r\n",i);
|
||||
sfud_read(sflash, new_appoffset+IMAGE_RW_SIZE*i, IMAGE_RW_SIZE, buf);
|
||||
printf("start erase write .\r\n");
|
||||
sfud_erase_write(sflash, imageoff+IMAGE_RW_SIZE*i, IMAGE_RW_SIZE, buf);
|
||||
printf("start erase write ok.\r\n");
|
||||
Set_sys_pace(i+1);
|
||||
if(i==0)
|
||||
{
|
||||
if (uup_file_type == UPFILE_TYPE_APP) {//代码文件
|
||||
unsigned int *tmp = (unsigned int *)(buf + NEW_APPLDR_CHECKSUM_OFFSET);
|
||||
appchecksum = *tmp;
|
||||
*tmp = 0;
|
||||
}else if (uup_file_type == UPFILE_TYPE_ANIMATION) {//动画文件
|
||||
BANIHEADER *pheader = (BANIHEADER *)buf;
|
||||
appchecksum = pheader->checksum;
|
||||
pheader->checksum = 0;
|
||||
}else if (uup_file_type == UPFILE_TYPE_RESOURCE) {//资源文件
|
||||
RomHeader *pheader = (RomHeader *)buf;
|
||||
appchecksum = pheader->checksum;
|
||||
pheader->checksum = 0;
|
||||
}
|
||||
printf("file_type = %d. %X\r\n",uup_file_type,appchecksum);
|
||||
calchecksum = xcrc32(buf, IMAGE_RW_SIZE, 0xffffffff);
|
||||
printf("i=0 calchecksum = 0x%X.\n",calchecksum);
|
||||
}
|
||||
else
|
||||
{
|
||||
calchecksum = xcrc32(buf, IMAGE_RW_SIZE, calchecksum);
|
||||
printf("i=%d ,r_add = 0x%X ,w_add = 0x%X , calchecksum = 0x%X.\n",i,new_appoffset+IMAGE_RW_SIZE*i,imageoff+IMAGE_RW_SIZE*i,calchecksum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(new_appsize%IMAGE_RW_SIZE)
|
||||
{
|
||||
uint32_t red_add,wri_add,size,count;
|
||||
int k;
|
||||
count = (new_appsize%IMAGE_RW_SIZE )/0x1000;
|
||||
red_add = new_appoffset+new_appsize- new_appsize%IMAGE_RW_SIZE;
|
||||
wri_add = imageoff+new_appsize- new_appsize%IMAGE_RW_SIZE;
|
||||
size = 0x1000;
|
||||
printf("count = %d .\n",count);
|
||||
for(k=0;k<count;k++){
|
||||
sfud_read(sflash, red_add, size, buf);
|
||||
sfud_erase_write(sflash, wri_add, size, buf);
|
||||
calchecksum = xcrc32(buf, size, calchecksum);
|
||||
printf("k=%d ,calchecksum = 0x%X.\n",k,calchecksum);
|
||||
red_add +=size;
|
||||
wri_add +=size;
|
||||
}
|
||||
|
||||
if(uup_buf_len){//若最后一包数据不满0x1000 则存数据并且继续计算校验和
|
||||
sfud_read(sflash, red_add, uup_buf_len, buf);
|
||||
sfud_erase_write(sflash, wri_add, uup_buf_len, buf);
|
||||
calchecksum = xcrc32(buf, uup_buf_len, calchecksum);
|
||||
printf("end calchecksum = 0x%X.\n",calchecksum);
|
||||
}
|
||||
}
|
||||
printf("end flash copy.\n");
|
||||
vPortFree(buf);
|
||||
printf("calchecksum is 0x%X\r\n",calchecksum);
|
||||
printf("appchecksum is 0x%X\r\n",appchecksum);
|
||||
if(calchecksum==appchecksum)
|
||||
{
|
||||
printf("crc32 OK\r\n");
|
||||
SysInfo *sysinfo = GetSysInfo();
|
||||
if(uup_file_type == UPFILE_TYPE_APP)
|
||||
sysinfo->app_size = new_appsize;
|
||||
sysinfo->image_offset=0x40000;
|
||||
sysinfo->upgrade_flag = 0;
|
||||
sysinfo->upgrade_appsize =0;
|
||||
sysinfo->reserved[9] = 0;
|
||||
SaveSysInfo();
|
||||
vTaskDelay(500);
|
||||
wdt_cpu_reboot();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SysInfo *sysinfo = GetSysInfo();
|
||||
sysinfo->image_offset=0x40000;
|
||||
sysinfo->upgrade_flag = 0;
|
||||
sysinfo->upgrade_appsize =0;
|
||||
sysinfo->reserved[9] = 0;
|
||||
SaveSysInfo();
|
||||
vTaskDelay(500);
|
||||
printf("crc32 ERROR\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
6
app/moto/protocol/ota_protocol.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef OTA_PROTOCOL_H
|
||||
#define OTA_PROTOCOL_H
|
||||
|
||||
#include "tkc/types_def.h"
|
||||
|
||||
#endif
|
@ -79,7 +79,8 @@ void pressure_buffer_event_handing(Pressure_t pressure,char buffer[],uint8_t typ
|
||||
pressure.temp = data;
|
||||
if(data>=70 && data<128){
|
||||
pressure.temp_state = 1;
|
||||
}
|
||||
}else
|
||||
pressure.temp_state = 0;
|
||||
//DEBUG_PRINT("%x, ",data);
|
||||
//P
|
||||
sum = 0;
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "moto_adc.h"
|
||||
|
||||
|
||||
// uint8_t save_data = 0;
|
||||
uint8_t save_data = 0;
|
||||
|
||||
#define ADC_VPLTAGE_MIN 1666
|
||||
#define ADC_VPLTAGE_MAX 2486
|
||||
@ -20,7 +20,7 @@ int adc_light = 0;
|
||||
int adc_voltage = 0;
|
||||
|
||||
extern uint32_t fml_stamp_to_time(uint32_t timep , uint32_t time[]);
|
||||
extern uint16_t light_buffer[];
|
||||
extern uint8_t light_buffer[];
|
||||
extern double cell_buffer[];
|
||||
extern uint8_t data_storage;
|
||||
extern uint32_t tire_front_time;
|
||||
@ -54,10 +54,10 @@ double adc_voltage_calculation(void){
|
||||
value = 16.5;
|
||||
else
|
||||
value = (adc_voltage - ADC_VPLTAGE_MIN) * (16.5 - 11.0) / (ADC_VPLTAGE_MAX - ADC_VPLTAGE_MIN) + 11.0;
|
||||
printf("adc_voltage = %d value = %lf.\r\n",adc_voltage,value);
|
||||
// printf("adc_voltage = %d value = %lf.\r\n",adc_voltage,value);
|
||||
return value;
|
||||
}
|
||||
extern uint8_t device_flag;
|
||||
|
||||
//MOTO通讯 设备信息+时间戳解析协议
|
||||
void device_data_analysis(uint8_t *buf){
|
||||
DEBUG_PRINT("enter device_data_analysis .\r\n");
|
||||
@ -77,8 +77,7 @@ void device_data_analysis(uint8_t *buf){
|
||||
// DEBUG_PRINT("0x47 -- %02x .\n",data);
|
||||
if(data!=0x47)
|
||||
return;
|
||||
if(!device_flag)
|
||||
device_flag = 1;
|
||||
|
||||
//设备相关信息
|
||||
data = *(buf++);//0x01
|
||||
// DEBUG_PRINT("0x01 -- %02x .\n",data);
|
||||
@ -199,7 +198,7 @@ void device_data_analysis(uint8_t *buf){
|
||||
Set_device_ability(data);
|
||||
|
||||
}
|
||||
|
||||
int test_light = 0;
|
||||
//MOTO通讯协议
|
||||
void data_analysis(uint8_t *buf){
|
||||
uint32_t data;
|
||||
@ -211,7 +210,8 @@ void data_analysis(uint8_t *buf){
|
||||
uint8_t light = 0;
|
||||
double cell = 0;
|
||||
uint8_t sys_state = 0;
|
||||
uint8_t save_data = 0;
|
||||
save_data = 0;
|
||||
|
||||
if(Get_sys_power_on_self_test()==100)
|
||||
sys_state=1;
|
||||
|
||||
@ -279,11 +279,14 @@ void data_analysis(uint8_t *buf){
|
||||
save_data = getBitValue(data,7);
|
||||
|
||||
if(sys_state){
|
||||
// right_led_switch(getBitValue(data,0));
|
||||
// left_led_switch(getBitValue(data,1));
|
||||
right_led_switch(getBitValue(data,0));
|
||||
left_led_switch(getBitValue(data,1));
|
||||
yg_led_switch(getBitValue(data,2));
|
||||
// abs_led_switch(getBitValue(data,4));
|
||||
// eng_led_switch(getBitValue(data,6));
|
||||
#if (MOTO_WARE_HOSE == MOTO_ICMX_A580A)
|
||||
abs_led_switch(getBitValue(data,4));
|
||||
eng_led_switch(getBitValue(data,6));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//档位
|
||||
@ -343,7 +346,7 @@ void data_analysis(uint8_t *buf){
|
||||
}
|
||||
|
||||
if(save_data){
|
||||
DEBUG_PRINT("save_data.\r\n");
|
||||
// DEBUG_PRINT("save_data.\r\n");
|
||||
// printf("light = %d .\r\n",light);
|
||||
Set_sys_gas(oil);
|
||||
Set_sys_temp(temp);
|
||||
@ -364,8 +367,11 @@ void data_analysis(uint8_t *buf){
|
||||
|
||||
//adc采样光感计算
|
||||
int light_num = (adc_light/10);
|
||||
if(light_num>=100)
|
||||
light_num = 100;
|
||||
test_light = light_num;
|
||||
if(light_num>=200)
|
||||
light_num = 200;
|
||||
if(Get_sys_power_on_self_test()<100)
|
||||
light_num = 10;
|
||||
light_buffer[data_storage] =light_num;
|
||||
data_storage++;
|
||||
if(data_storage>=SAVE_DATA_SIZE){//满足存储大小 计算均值
|
||||
|
@ -3,4 +3,14 @@
|
||||
|
||||
#include "tkc/types_def.h"
|
||||
|
||||
// 封装的函数,根据位位置获取对应的值
|
||||
uint8_t getBitValue(uint8_t count, int bitPosition);
|
||||
// 封装的函数,获取2个bit组合成的值
|
||||
uint8_t getBit2Value(uint8_t count, int bitPosition);
|
||||
// 封装的函数,获取3个bit组合成的值
|
||||
uint8_t getBit3Value(uint8_t count, int bitPosition);
|
||||
// 封装的函数,获取4个bit组合成的值
|
||||
uint8_t getBit4Value(uint8_t count, int bitPosition);
|
||||
|
||||
|
||||
#endif
|
||||
|
21
lib/awtk/awtk-examples/.gitignore
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
__docs__
|
||||
__images__
|
||||
bin/
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
*.swp
|
||||
*.pdb
|
||||
*.ilk
|
||||
*.idb
|
||||
*.obj
|
||||
*.lib
|
||||
*.exp
|
||||
*.doc
|
||||
*.docx
|
||||
*.vsd
|
||||
.sconsign.dblite
|
||||
.vscode
|
||||
build_web.py
|
||||
Moto_A58/res/assets/
|
||||
Moto_QH105/
|
BIN
lib/awtk/awtk-examples/Moto_A58-0901.zip
Normal file
115
lib/awtk/awtk-examples/Moto_A58/3rd/awtk-widget-qr/.clang-format
Normal file
@ -0,0 +1,115 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: Google
|
||||
AccessModifierOffset: -1
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
AllowShortIfStatementsOnASingleLine: true
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IncludeCategories:
|
||||
- Regex: '^<ext/.*\.h>'
|
||||
Priority: 2
|
||||
- Regex: '^<.*\.h>'
|
||||
Priority: 1
|
||||
- Regex: '^<.*'
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
||||
IndentCaseLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: false
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 1
|
||||
PenaltyBreakComment: 600
|
||||
PenaltyBreakFirstLessLess: 100
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Left
|
||||
RawStringFormats:
|
||||
- Language: TextProto
|
||||
BasedOnStyle: google
|
||||
ReflowComments: false
|
||||
SortIncludes: false
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 2
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Auto
|
||||
TabWidth: 2
|
||||
UseTab: Never
|
||||
...
|
||||
|
34
lib/awtk/awtk-examples/Moto_A58/3rd/awtk-widget-qr/.gitignore
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
*.swp
|
||||
*.pdb
|
||||
*.ilk
|
||||
*.idb
|
||||
*.obj
|
||||
*.exe
|
||||
*.os
|
||||
*.pyc
|
||||
/bin
|
||||
/lib
|
||||
.sconsign.dblite
|
||||
lua/demo1
|
||||
lua/lftk_run
|
||||
tags
|
||||
bin/demo1*
|
||||
bin/demo_animator*
|
||||
bin/demo_thread*
|
||||
bin/demotr*
|
||||
bin/demovg*
|
||||
bin/fontgen*
|
||||
bin/preview_ui*
|
||||
bin/resgen*
|
||||
bin/runLua*
|
||||
bin/runTest*
|
||||
bin/strgen*
|
||||
bin/image*
|
||||
bin/hello*
|
||||
.vscode
|
||||
.vs
|
||||
*.os
|
||||
res
|
504
lib/awtk/awtk-examples/Moto_A58/3rd/awtk-widget-qr/LICENSE
Normal file
@ -0,0 +1,504 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random
|
||||
Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
143
lib/awtk/awtk-examples/Moto_A58/3rd/awtk-widget-qr/README.md
Normal file
@ -0,0 +1,143 @@
|
||||
# awtk-widget-qr
|
||||
|
||||
qr 控件。用于显示二维码控件。
|
||||
|
||||

|
||||
|
||||
* 本项目使用 [libqrencode](https://github.com/fukuchi/libqrencode) 生成二维码。
|
||||
|
||||
* 本项目使用 [awtk-widget-generator](https://github.com/zlgopen/awtk-widget-generator) 生成代码框架。
|
||||
|
||||
## 准备
|
||||
|
||||
1. 获取 awtk 并编译
|
||||
|
||||
```
|
||||
git clone https://github.com/zlgopen/awtk.git
|
||||
cd awtk; scons; cd -
|
||||
```
|
||||
|
||||
2. 获取 awtk-widget-qr 并编译
|
||||
```
|
||||
git clone https://github.com/zlgopen/awtk-widget-qr.git
|
||||
cd awtk-widget-qr; scons
|
||||
```
|
||||
|
||||
## 运行
|
||||
|
||||
1. 生成示例代码的资源
|
||||
|
||||
```
|
||||
python scripts/update_res.py all
|
||||
```
|
||||
> 也可以使用 Designer 打开项目,之后点击 “打包” 按钮进行生成;
|
||||
> 如果资源发生修改,则需要重新生成资源。
|
||||
|
||||
如果 PIL 没有安装,执行上述脚本可能会出现如下错误:
|
||||
```cmd
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ModuleNotFoundError: No module named 'PIL'
|
||||
```
|
||||
请用 pip 安装:
|
||||
```cmd
|
||||
pip install Pillow
|
||||
```
|
||||
|
||||
2. 编译
|
||||
|
||||
* 编译PC版本
|
||||
|
||||
```
|
||||
scons
|
||||
```
|
||||
|
||||
* 编译LINUX FB版本
|
||||
|
||||
```
|
||||
scons LINUX_FB=true
|
||||
```
|
||||
|
||||
> 完整编译选项请参考[编译选项](https://github.com/zlgopen/awtk-widget-generator/blob/master/docs/build_options.md)
|
||||
|
||||
|
||||
3. 运行
|
||||
|
||||
```
|
||||
./bin/demo
|
||||
```
|
||||
|
||||
## 如何使用二维码控件
|
||||
|
||||
### 设置需要转成二维码的字符串
|
||||
|
||||
qr 控件 `value` 属性内容就是转成二维码的字符串内容。
|
||||
|
||||
在界面描述文件设置:
|
||||
|
||||
```xml
|
||||
<window theme="main" name="main">
|
||||
<qr name="qr" x="c" y="m" w="50%" h="50%" value="https://github.com/zlgopen/awtk"/>
|
||||
</window>
|
||||
```
|
||||
|
||||
或在代码中设置:
|
||||
|
||||
```c
|
||||
widget_t* win = window_open("main");
|
||||
widget_t* qr = widget_lookup(win, "qr", TRUE);
|
||||
qr_set_value(qr, "https://github.com/zlgopen/awtk");
|
||||
```
|
||||
|
||||
按照上述例子设置完成后,用手机扫该二维码就会打开[ https://github.com/zlgopen/awtk ](https://github.com/zlgopen/awtk)网址。
|
||||
|
||||
### 设置二维码中的颜色与图片
|
||||
|
||||
添加图片资源到项目中:
|
||||
|
||||

|
||||
|
||||
在样式文件中设置 qr 控件样式在对应状态设置 `fg_color` ,`bg_color`,`bg_image` 属性:
|
||||
|
||||
```xml
|
||||
<qr>
|
||||
<style name="default">
|
||||
<!-- fg_color 为二维码颜色,bg_color 为二维码背景色 -->
|
||||
<normal fg_color="black" bg_color="white" bg_image="message"/>
|
||||
|
||||
<!-- disable 状态用于模拟 被扫描 状态 -->
|
||||
<!-- 不设置 bg_image 属性,则该状态二维码中间没有图片 -->
|
||||
<disable fg_color="gray" bg_color="#f0f0f0"/>
|
||||
</style>
|
||||
</qr>
|
||||
```
|
||||
|
||||
从上述例子得到的效果为:
|
||||
|
||||
正常状态:
|
||||
|
||||

|
||||
|
||||
被扫描状态:
|
||||
|
||||

|
||||
|
||||
**注意**:图片大小不可以大于二维码的 `45%` ,否则图片将会被裁剪:
|
||||
|
||||
图片资源:
|
||||
|
||||

|
||||
|
||||
得到的二维码:
|
||||
|
||||

|
||||
|
||||
qr 控件的属性名及作用如下表所示:
|
||||
|
||||
| 属性名 | 作用 |
|
||||
| ------ | ---------------------- |
|
||||
| value | 要转换为二维码的字符串 |
|
||||
|
||||
## 文档
|
||||
|
||||
[完善自定义控件](https://github.com/zlgopen/awtk-widget-generator/blob/master/docs/improve_generated_widget.md)
|
@ -0,0 +1,8 @@
|
||||
import os
|
||||
import scripts.app_helper as app
|
||||
|
||||
helper = app.Helper(ARGUMENTS)
|
||||
helper.set_dll_def('src/qr.def').set_libs(['qr']).call(DefaultEnvironment)
|
||||
|
||||
SConscriptFiles = ['src/SConscript']
|
||||
SConscript(SConscriptFiles)
|
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 9.8 KiB |
After Width: | Height: | Size: 25 KiB |
@ -0,0 +1,459 @@
|
||||
<window>
|
||||
<style name="default">
|
||||
<normal bg_color="#ffffff"/>
|
||||
</style>
|
||||
</window>
|
||||
|
||||
<dialog>
|
||||
<style name="default" border_color="#c2c2c2">
|
||||
<normal bg_color="#ffffff"/>
|
||||
</style>
|
||||
</dialog>
|
||||
|
||||
<popup>
|
||||
<style name="default" border_color="#c2c2c2">
|
||||
<normal bg_color="#ffffff"/>
|
||||
</style>
|
||||
</popup>
|
||||
|
||||
<overlay>
|
||||
<style name="default" border_color="#c2c2c2">
|
||||
<normal bg_color="#ffffff"/>
|
||||
</style>
|
||||
</overlay>
|
||||
|
||||
<system_bar>
|
||||
<style name="default" border="bottom" border_color="#c2c2c2">
|
||||
<normal bg_color="#ffffff"/>
|
||||
</style>
|
||||
</system_bar>
|
||||
|
||||
<system_bar_bottom>
|
||||
<style name="default" border="top" border_color="#c2c2c2">
|
||||
<normal bg_color="#ffffff"/>
|
||||
</style>
|
||||
</system_bar_bottom>
|
||||
|
||||
<keyboard>
|
||||
<style name="default" border_color="#c2c2c2">
|
||||
<normal bg_color="#e1e1e1"/>
|
||||
</style>
|
||||
</keyboard>
|
||||
|
||||
<button>
|
||||
<style name="default" round_radius="4">
|
||||
<normal text_color="#444444" bg_color="#f4f4f4" border_color="#c2c2c2"/>
|
||||
<pressed text_color="#ffffff" bg_color="#1971dd" border_color="#1971dd"/>
|
||||
<over text_color="#ffffff" bg_color="#338fff" border_color="#338fff"/>
|
||||
<focused text_color="#444444" bg_color="#f4f4f4" border_color="#338fff" />
|
||||
<disable text_color="#44444466" bg_color="#f4f4f466" border_color="#c2c2c266" />
|
||||
</style>
|
||||
|
||||
<style name="combobox_down" border_color="#c2c2c2" bg_color="#f2f2f2">
|
||||
<normal icon="arrow_down_n"/>
|
||||
<pressed icon="arrow_down_p"/>
|
||||
<over icon="arrow_down_o"/>
|
||||
<disable icon="arrow_down_d" border_color="#c2c2c266" bg_color="#f2f2f266"/>
|
||||
</style>
|
||||
|
||||
<style name="spinbox_down" border_color="#c2c2c2" bg_color="#f2f2f2">
|
||||
<normal icon="arrow_down_n"/>
|
||||
<pressed icon="arrow_down_p"/>
|
||||
<over icon="arrow_down_o"/>
|
||||
<disable icon="arrow_down_d" border_color="#c2c2c266" bg_color="#f2f2f266"/>
|
||||
</style>
|
||||
|
||||
<style name="spinbox_up" border_color="#c2c2c2" bg_color="#f2f2f2">
|
||||
<normal icon="arrow_up_n"/>
|
||||
<pressed icon="arrow_up_p"/>
|
||||
<over icon="arrow_up_o"/>
|
||||
<disable icon="arrow_up_d" border_color="#c2c2c266" bg_color="#f2f2f266"/>
|
||||
</style>
|
||||
|
||||
<style name="spinbox_left" border_color="#c2c2c2" bg_color="#f2f2f2">
|
||||
<normal icon="arrow_left_n"/>
|
||||
<pressed icon="arrow_left_p"/>
|
||||
<over icon="arrow_left_o"/>
|
||||
<disable icon="arrow_left_d" border_color="#c2c2c266" bg_color="#f2f2f266"/>
|
||||
</style>
|
||||
|
||||
<style name="spinbox_right" border_color="#c2c2c2" bg_color="#f2f2f2">
|
||||
<normal icon="arrow_right_n"/>
|
||||
<pressed icon="arrow_right_p"/>
|
||||
<over icon="arrow_right_o"/>
|
||||
<disable icon="arrow_right_d" border_color="#c2c2c266" bg_color="#f2f2f266"/>
|
||||
</style>
|
||||
|
||||
<style name="scroll_down" bg_color="#f2f2f2">
|
||||
<normal icon="arrow_down_n"/>
|
||||
<pressed icon="arrow_down_p"/>
|
||||
<over icon="arrow_down_o"/>
|
||||
<disable icon="arrow_down_d" border_color="#c2c2c266" bg_color="#f2f2f266"/>
|
||||
</style>
|
||||
|
||||
<style name="scroll_up" bg_color="#f2f2f2">
|
||||
<normal icon="arrow_up_n"/>
|
||||
<pressed icon="arrow_up_p"/>
|
||||
<over icon="arrow_up_o"/>
|
||||
<disable icon="arrow_up_d" bg_color="#f2f2f266"/>
|
||||
</style>
|
||||
|
||||
<style name="scroll_left" bg_color="#f2f2f2">
|
||||
<normal icon="arrow_left_n"/>
|
||||
<pressed icon="arrow_left_p"/>
|
||||
<over icon="arrow_left_o"/>
|
||||
<disable icon="arrow_left_d" bg_color="#f2f2f266"/>
|
||||
</style>
|
||||
|
||||
<style name="scroll_right" bg_color="#f2f2f2">
|
||||
<normal icon="arrow_right_n"/>
|
||||
<pressed icon="arrow_right_p"/>
|
||||
<over icon="arrow_right_o"/>
|
||||
<disable icon="arrow_right_d" bg_color="#f2f2f266"/>
|
||||
</style>
|
||||
|
||||
</button>
|
||||
|
||||
<edit selected_text_color="#010101" selected_bg_color="#b5d7fd">
|
||||
<style name="default" bg_color="#f7f7f7" text_color="#444444" text_align_h="left">
|
||||
<normal border_color="#c2c2c2"/>
|
||||
<focused border_color="#338fff"/>
|
||||
<disable bg_color="#f7f7f766" border_color="#c2c2c266" text_color="#44444466" />
|
||||
<error border_color="#ff0000" />
|
||||
<empty border_color="#c2c2c2" text_color="#959494"/>
|
||||
<empty_focus border_color="#c2c2c2" text_color="#959494"/>
|
||||
<over border_color="#338fff"/>
|
||||
</style>
|
||||
</edit>
|
||||
|
||||
|
||||
<spin_box selected_text_color="#010101" selected_bg_color="#b5d7fd">
|
||||
<style name="default" bg_color="#f7f7f7" text_color="#444444" text_align_h="left">
|
||||
<normal border_color="#c2c2c2"/>
|
||||
<focused border_color="#338fff"/>
|
||||
<disable bg_color="#f7f7f766" border_color="#c2c2c266" text_color="#44444466"/>
|
||||
<error border_color="#ff0000"/>
|
||||
<empty border_color="#c2c2c2" text_color="#959494"/>
|
||||
<empty_focus border_color="#c2c2c2" text_color="#959494"/>
|
||||
<over border_color="#338fff"/>
|
||||
<has_value has_value="1"/>
|
||||
</style>
|
||||
</spin_box>
|
||||
|
||||
<digit_clock>
|
||||
<style name="default">
|
||||
<normal text_color="#444444" />
|
||||
</style>
|
||||
</digit_clock>
|
||||
|
||||
<label>
|
||||
<style name="default">
|
||||
<normal text_color="#444444"/>
|
||||
<disable text_color="#44444466"/>
|
||||
</style>
|
||||
</label>
|
||||
|
||||
<progress_bar>
|
||||
<style name="default" round_radius="5">
|
||||
<normal text_color="#444444" bg_color="#d8d8d8" fg_color="#338fff" border_color="#d8d8d8"/>
|
||||
<disable text_color="#44444466" bg_color="#d8d8d866" fg_color="#338fff66" border_color="#d8d8d866"/>
|
||||
</style>
|
||||
</progress_bar>
|
||||
|
||||
<slider>
|
||||
<style name="default" round_radius="5">
|
||||
<normal bg_color="#d8d8d8" fg_color="#338fff" border_color="#bfbfbf"/>
|
||||
<pressed bg_color="#d8d8d8" fg_color="#338fff" border_color="#1456d6"/>
|
||||
<over bg_color="#d8d8d8" fg_color="#338fff" border_color="#54d8ff"/>
|
||||
<focused bg_color="#d8d8d8" fg_color="#338fff" border_color="#54d8ff"/>
|
||||
<disable bg_color="#d8d8d866" fg_color="#338fff66" border_color="#ececec"/>
|
||||
</style>
|
||||
</slider>
|
||||
|
||||
<check_button>
|
||||
<style name="default" icon_at="left" text_color="#444444">
|
||||
<normal icon="check_unchecked" />
|
||||
<pressed icon="check_unchecked" />
|
||||
<over icon="check_unchecked" />
|
||||
<focused icon="check_unchecked" />
|
||||
<disable icon="check_unchecked_d" text_color="#44444466"/>
|
||||
<normal_of_checked icon="check_checked" />
|
||||
<pressed_of_checked icon="check_checked" />
|
||||
<over_of_checked icon="check_checked" />
|
||||
<focused_of_checked icon="check_checked" />
|
||||
<disable_of_checked icon="check_checked_d" text_color="#44444466"/>
|
||||
</style>
|
||||
</check_button>
|
||||
|
||||
<radio_button>
|
||||
<style name="default" text_color="#444444" icon_at="left">
|
||||
<normal icon="radio_unchecked" />
|
||||
<pressed icon="radio_unchecked" />
|
||||
<over icon="radio_unchecked" />
|
||||
<focused icon="radio_unchecked" />
|
||||
<disable icon="radio_unchecked_d" text_color="#44444466"/>
|
||||
<normal_of_checked icon="radio_checked"/>
|
||||
<pressed_of_checked icon="radio_checked"/>
|
||||
<over_of_checked icon="radio_checked"/>
|
||||
<focused_of_checked icon="radio_checked" />
|
||||
<disable_of_checked icon="radio_checked_d" text_color="#44444466"/>
|
||||
</style>
|
||||
</radio_button>
|
||||
|
||||
<image>
|
||||
<style name="default" text_color="#444444">
|
||||
<normal />
|
||||
</style>
|
||||
</image>
|
||||
|
||||
<scroll_bar_m>
|
||||
<style name="default">
|
||||
<normal fg_color="#808080"/>
|
||||
<disable fg_color="#80808066"/>
|
||||
</style>
|
||||
</scroll_bar_m>
|
||||
|
||||
<scroll_bar_d>
|
||||
<style name="default" border_color="#bebebe">
|
||||
<normal bg_color="#f0f0f0"/>
|
||||
<over bg_color="#f0f0f0" />
|
||||
<pressed bg_color="#f0f0f0" />
|
||||
<disable bg_color="#f0f0f066" border_color="#bebebe66"/>
|
||||
</style>
|
||||
</scroll_bar_d>
|
||||
|
||||
<dragger>
|
||||
<style name="default" bg_color="#9e9e9e">
|
||||
<normal />
|
||||
<pressed />
|
||||
<over />
|
||||
</style>
|
||||
<style name="scroll_bar">
|
||||
<normal bg_color="#d0d0d0" />
|
||||
<pressed bg_color="#c0c0c0" />
|
||||
<over bg_color="#c0c0c0" />
|
||||
<disable bg_color="#c0c0c066" />
|
||||
</style>
|
||||
</dragger>
|
||||
|
||||
<list_item>
|
||||
<style name="default" border_color="#e9e9e9" text_color="#444444">
|
||||
<normal bg_color="#ffffff" />
|
||||
<pressed bg_color="#338fff" text_color="#ffffff" />
|
||||
<over bg_color="#ffffff" border_color="#338fff"/>
|
||||
<disable border_color="#e9e9e966" text_color="#44444466"/>
|
||||
</style>
|
||||
</list_item>
|
||||
|
||||
<tab_button>
|
||||
<style name="default" border_color="#c2c2c2" text_color="#444444">
|
||||
<normal bg_color="#f4f4f4" />
|
||||
<pressed bg_color="#cecdcd" />
|
||||
<over bg_color="#ffffff" text_color="#1971dd"/>
|
||||
<normal_of_active bg_color="#ffffff" border="top|left|right"/>
|
||||
<pressed_of_active bg_color="#ffffff" text_color="#1971dd" border="top|left|right"/>
|
||||
<over_of_active bg_color="#ffffff" text_color="#1971dd" border="top|left|right"/>
|
||||
<disable_of_active border_color="#c2c2c266" bg_color="#f4f4f466" text_color="#44444466" border="top|left|right"/>
|
||||
<disable border_color="#c2c2c266" bg_color="#f4f4f466" text_color="#44444466"/>
|
||||
</style>
|
||||
</tab_button>
|
||||
|
||||
<tab_button_group >
|
||||
<style name="default">
|
||||
<normal/>
|
||||
</style>
|
||||
|
||||
<style name="scrollable" border_color="#a0a0a0" border="left|right">
|
||||
<normal/>
|
||||
</style>
|
||||
</tab_button_group>
|
||||
|
||||
|
||||
<combo_box selected_text_color="#010101" selected_bg_color="#b5d7fd">
|
||||
<style name="default" bg_color="#f7f7f7" text_color="#444444" text_align_h="left" border_color="#c2c2c2">
|
||||
<normal border_color="#c2c2c2"/>
|
||||
<focused border_color="#338fff"/>
|
||||
<disable bg_color="#f7f7f766" border_color="#c2c2c266" text_color="#44444466"/>
|
||||
<error border_color="#ff0000"/>
|
||||
<empty border_color="#c2c2c2" text_color="#959494"/>
|
||||
<empty_focus border_color="#c2c2c2" text_color="#959494"/>
|
||||
<over border_color="#338fff"/>
|
||||
</style>
|
||||
</combo_box>
|
||||
|
||||
|
||||
<combo_box_ex selected_text_color="#010101" selected_bg_color="#b5d7fd">
|
||||
<style name="default" bg_color="#f7f7f7" text_color="#444444" text_align_h="left" border_color="#c2c2c2">
|
||||
<normal border_color="#c2c2c2"/>
|
||||
<focused border_color="#338fff"/>
|
||||
<disable bg_color="#f7f7f766" border_color="#c2c2c266" text_color="#44444466"/>
|
||||
<error border_color="#ff0000"/>
|
||||
<empty border_color="#c2c2c2" text_color="#959494"/>
|
||||
<empty_focus border_color="#c2c2c2" text_color="#959494"/>
|
||||
<over border_color="#338fff"/>
|
||||
</style>
|
||||
</combo_box_ex>
|
||||
|
||||
<combo_box_item>
|
||||
<style name="default" icon_at="left" text_color="#444444" bg_color="#ffffff">
|
||||
<normal />
|
||||
<pressed bg_color="#338fff" text_color="#ffffff" />
|
||||
<over bg_color="#1971dd" text_color="#ffffff" />
|
||||
<focused bg_color="#1296db" text_color="#ffffff" />
|
||||
<normal_of_checked bg_color="#338fff" text_color="#ffffff"/>
|
||||
<focused_of_checked bg_color="#338fff" text_color="#ffffff"/>
|
||||
<pressed_of_checked bg_color="#338fff" text_color="#ffffff" />
|
||||
<over_of_checked bg_color="#1971dd" text_color="#ffffff" />
|
||||
<disable_of_checked bg_color="#f4f4f466" text_color="#44444466" />
|
||||
<disable bg_color="#f4f4f466" text_color="#44444466"/>
|
||||
</style>
|
||||
</combo_box_item>
|
||||
|
||||
<text_selector>
|
||||
<style name="default" fg_color="#c2c2c2" text_color="#444444" text_align_h="center" bg_color="#ffffff">
|
||||
<normal mask_color="#404040" border_color="#c2c2c2"/>
|
||||
<disable mask_color="#c0c0c0" border_color="#c2c2c266" text_color="#44444466" />
|
||||
</style>
|
||||
</text_selector>
|
||||
|
||||
<switch>
|
||||
<style name="default" margin="2" round_radius="11" fg_color="#ffffff">
|
||||
<normal bg_color="#828282" selected_bg_color="#338fff"/>
|
||||
<disable bg_color="#82828266" selected_bg_color="#338fff66"/>
|
||||
</style>
|
||||
</switch>
|
||||
|
||||
<slide_indicator>
|
||||
<style name="default">
|
||||
<normal fg_color="#338fff40" selected_fg_color="#338fff"/>
|
||||
<disable fg_color="#338fff20" selected_fg_color="#338fff66"/>
|
||||
</style>
|
||||
</slide_indicator>
|
||||
|
||||
<slide_indicator_arc>
|
||||
<style name="default">
|
||||
<normal fg_color="#338fff40" selected_fg_color="#338fff"/>
|
||||
<disable fg_color="#338fff20" selected_fg_color="#338fff66"/>
|
||||
</style>
|
||||
</slide_indicator_arc>
|
||||
|
||||
|
||||
<progress_circle>
|
||||
<style name="default">
|
||||
<normal text_color="#444444" fg_color="#338fff"/>
|
||||
<disable text_color="#44444466" fg_color="#338fff66"/>
|
||||
</style>
|
||||
</progress_circle>
|
||||
|
||||
<svg>
|
||||
<style name="default" text_color="#444444">
|
||||
<normal/>
|
||||
</style>
|
||||
</svg>
|
||||
|
||||
<gif>
|
||||
<style name="default">
|
||||
<normal/>
|
||||
</style>
|
||||
</gif>
|
||||
|
||||
<slide_menu>
|
||||
<style name="default">
|
||||
<normal/>
|
||||
</style>
|
||||
</slide_menu>
|
||||
|
||||
<mledit selected_fg_color="#020202" selected_text_color="#010101" selected_bg_color="#b5d7fd">
|
||||
<style name="default" border_color="#a0a0a0" text_color="#444444" text_align_h="left">
|
||||
<normal bg_color="#ffffff" />
|
||||
<focused bg_color="#ffffff"/>
|
||||
<disable bg_color="gray" text_color="#44444466" />
|
||||
<error bg_color="#ffffff" text_color="red" />
|
||||
<empty bg_color="#ffffff" text_color="#a0a0a0" />
|
||||
<empty_focus bg_color="#ffffff" text_color="#a0a0a0"/>
|
||||
</style>
|
||||
</mledit>
|
||||
|
||||
<line_number>
|
||||
<style name="default" text_align_h="center">
|
||||
<normal text_color="#444444" bg_color="#d0d0d0"/>
|
||||
<disable text_color="#44444466" bg_color="#d0d0d066"/>
|
||||
</style>
|
||||
</line_number>
|
||||
|
||||
<hscroll_label>
|
||||
<style name="default" text_color="#444444">
|
||||
<normal />
|
||||
<disable text_color="#44444466"/>
|
||||
</style>
|
||||
</hscroll_label>
|
||||
|
||||
<color_tile>
|
||||
<style name="default">
|
||||
<normal border_color="#c2c2c2"/>
|
||||
<focused border_color="#338fff"/>
|
||||
<disable border_color="#c2c2c266"/>
|
||||
</style>
|
||||
</color_tile>
|
||||
|
||||
<view>
|
||||
<style name="default">
|
||||
<normal />
|
||||
</style>
|
||||
</view>
|
||||
|
||||
<tab_control>
|
||||
<style name="default">
|
||||
<normal />
|
||||
</style>
|
||||
</tab_control>
|
||||
|
||||
<scroll_view>
|
||||
<style name="default">
|
||||
<normal />
|
||||
</style>
|
||||
</scroll_view>
|
||||
|
||||
<list_view>
|
||||
<style name="default" border_color="#c2c2c2" bg_color="#f4f4f4">
|
||||
<normal />
|
||||
<disable border_color="#c2c2c266" bg_color="#f4f4f466"/>
|
||||
</style>
|
||||
</list_view>
|
||||
|
||||
<list_view_h>
|
||||
<style name="default" border_color="#c2c2c2" bg_color="#f4f4f4">
|
||||
<normal />
|
||||
<disable border_color="#c2c2c266" bg_color="#f4f4f466"/>
|
||||
</style>
|
||||
</list_view_h>
|
||||
|
||||
<pages>
|
||||
<style name="default" border_color="#c2c2c2">
|
||||
<normal />
|
||||
</style>
|
||||
</pages>
|
||||
|
||||
<slide_view>
|
||||
<style name="default">
|
||||
<normal />
|
||||
</style>
|
||||
</slide_view>
|
||||
|
||||
<color_picker>
|
||||
<style name="default">
|
||||
<normal />
|
||||
</style>
|
||||
</color_picker>
|
||||
|
||||
<color_component>
|
||||
<style name="default" border_color="#c2c2c2">
|
||||
<normal />
|
||||
</style>
|
||||
</color_component>
|
||||
|
||||
<candidates>
|
||||
<style name="default" text_color="#444444" bg_color="#fafafa">
|
||||
<normal />
|
||||
</style>
|
||||
</candidates>
|
@ -0,0 +1,6 @@
|
||||
<qr>
|
||||
<style name="default" >
|
||||
<normal fg_color="black" bg_color="white" bg_image="message"/>
|
||||
<disable fg_color="gray" bg_color="#f0f0f0"/>
|
||||
</style>
|
||||
</qr>
|
@ -0,0 +1,4 @@
|
||||
<window theme="main">
|
||||
<qr x="c" y="m" w="240" h="240" value="https://github.com/zlgopen/awtk"/>
|
||||
<button x="c" y="b:30" w="80" h="30" name="close" text="Close"/>
|
||||
</window>
|
@ -0,0 +1,6 @@
|
||||
### 2021/11/25
|
||||
* 去除没有使用到的宏和变量(感谢兆坤提供补丁)
|
||||
* 修复logo裁剪区域未还原导致的界面显示问题(感谢兆坤提供补丁)
|
||||
|
||||
### 2021/10/26
|
||||
* 中间支持LOGO(感谢兆坤提供补丁)
|
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 9.4 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 58 KiB |
@ -0,0 +1,6 @@
|
||||
find src -name \*.c -exec clang-format -i {} \;
|
||||
find src -name \*.h -exec clang-format -i {} \;
|
||||
find src -name \*.cc -exec clang-format -i {} \;
|
||||
find src -name \*.cpp -exec clang-format -i {} \;
|
||||
find src -name \*.inc -exec clang-format -i {} \;
|
||||
|
@ -0,0 +1,3 @@
|
||||
|
||||
node ../awtk/tools/idl_gen/index.js idl/idl.json src/
|
||||
node ../awtk/tools/dll_def_gen/index.js idl/idl.json src/qr.def
|
154
lib/awtk/awtk-examples/Moto_A58/3rd/awtk-widget-qr/idl/idl.json
Normal file
@ -0,0 +1,154 @@
|
||||
[
|
||||
{
|
||||
"params": [],
|
||||
"annotation": {
|
||||
"global": true
|
||||
},
|
||||
"desc": "注册控件。",
|
||||
"name": "qr_register",
|
||||
"return": {
|
||||
"type": "ret_t",
|
||||
"desc": "返回RET_OK表示成功,否则表示失败。"
|
||||
},
|
||||
"type": "method",
|
||||
"header": "src/qr_register.h",
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"params": [],
|
||||
"annotation": {
|
||||
"global": true
|
||||
},
|
||||
"desc": "获取支持的渲染模式。",
|
||||
"name": "qr_supported_render_mode",
|
||||
"return": {
|
||||
"type": "const char*",
|
||||
"desc": "返回渲染模式。"
|
||||
},
|
||||
"type": "method",
|
||||
"header": "src/qr_register.h",
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"type": "class",
|
||||
"methods": [
|
||||
{
|
||||
"params": [
|
||||
{
|
||||
"type": "widget_t*",
|
||||
"name": "parent",
|
||||
"desc": "父控件"
|
||||
},
|
||||
{
|
||||
"type": "xy_t",
|
||||
"name": "x",
|
||||
"desc": "x坐标"
|
||||
},
|
||||
{
|
||||
"type": "xy_t",
|
||||
"name": "y",
|
||||
"desc": "y坐标"
|
||||
},
|
||||
{
|
||||
"type": "wh_t",
|
||||
"name": "w",
|
||||
"desc": "宽度"
|
||||
},
|
||||
{
|
||||
"type": "wh_t",
|
||||
"name": "h",
|
||||
"desc": "高度"
|
||||
}
|
||||
],
|
||||
"annotation": {
|
||||
"constructor": true,
|
||||
"scriptable": true
|
||||
},
|
||||
"desc": "创建qr对象",
|
||||
"name": "qr_create",
|
||||
"return": {
|
||||
"type": "widget_t*",
|
||||
"desc": "qr对象。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"params": [
|
||||
{
|
||||
"type": "widget_t*",
|
||||
"name": "widget",
|
||||
"desc": "qr对象。"
|
||||
}
|
||||
],
|
||||
"annotation": {
|
||||
"cast": true,
|
||||
"scriptable": true
|
||||
},
|
||||
"desc": "转换为qr对象(供脚本语言使用)。",
|
||||
"name": "qr_cast",
|
||||
"return": {
|
||||
"type": "widget_t*",
|
||||
"desc": "qr对象。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"params": [
|
||||
{
|
||||
"type": "widget_t*",
|
||||
"name": "widget",
|
||||
"desc": "widget对象。"
|
||||
},
|
||||
{
|
||||
"type": "const char*",
|
||||
"name": "value",
|
||||
"desc": "格式字符串。"
|
||||
}
|
||||
],
|
||||
"annotation": {
|
||||
"scriptable": true
|
||||
},
|
||||
"desc": "设置要转成二维码的字符串。",
|
||||
"name": "new_qr_set_value",
|
||||
"return": {
|
||||
"type": "ret_t",
|
||||
"desc": "返回RET_OK表示成功,否则表示失败。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"params": [],
|
||||
"annotation": {},
|
||||
"desc": "获取 qr 虚表。",
|
||||
"name": "qr_get_widget_vtable",
|
||||
"return": {
|
||||
"type": "const widget_vtable_t*",
|
||||
"desc": "成功返回 qr 虚表。"
|
||||
}
|
||||
}
|
||||
],
|
||||
"events": [],
|
||||
"properties": [
|
||||
{
|
||||
"name": "value",
|
||||
"desc": "要转成二维码的字符串。值。",
|
||||
"type": "char*",
|
||||
"annotation": {
|
||||
"set_prop": true,
|
||||
"get_prop": true,
|
||||
"readable": true,
|
||||
"persitent": true,
|
||||
"design": true,
|
||||
"scriptable": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"header": "qr/qr.h",
|
||||
"desc": "显示二维码的控件\nqr\\_t是[widget\\_t](widget_t.md)的子类控件,widget\\_t的函数均适用于qr\\_t控件。\n\n在xml中使用\"qr\"标签创建数值文本控件。如:\n\n```xml\n<!-- ui -->\n<qr x=\"c\" y=\"m\" w=\"240\" h=\"240\" value=\"https://github.com/zlgopen/awtk\"/>\n```\n在c代码中使用函数qr\\_create创建数值文本控件。如:\n\n```c\nwidget_t* qr = qr_create(win, 10, 10, 128, 128);\n```\n可用通过style来设置控件的显示风格,如字体的大小和颜色等等。如:\n\n```xml\n<!-- style -->\n<qr>\n<style name=\"default\" >\n<normal fg_color=\"black\" bg_color=\"white\" bg_image=\"message\"/>\n<disable fg_color=\"gray\" bg_color=\"#f0f0f0\"/>\n</style>\n</qr>\n```",
|
||||
"name": "qr_t",
|
||||
"parent": "widget_t",
|
||||
"annotation": {
|
||||
"scriptable": true,
|
||||
"design": true,
|
||||
"widget": true
|
||||
},
|
||||
"level": 2
|
||||
}
|
||||
]
|
@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "qr",
|
||||
"version": "1.0.1",
|
||||
"date": "2020-06-01",
|
||||
"team": "AWTK Develop Team",
|
||||
"author": "Li XianJing <xianjimli@hotmail.com>",
|
||||
"desc": "显示二维码的控件",
|
||||
"copyright": "Guangzhou ZHIYUAN Electronics Co.,Ltd.",
|
||||
"type": "PROJECT_CUSTOM_WIDGET",
|
||||
"entry": "main",
|
||||
"assets": {
|
||||
"activedTheme": "default",
|
||||
"outputDir": "res",
|
||||
"loadFrom": "any",
|
||||
"const": "resource_data",
|
||||
"screenDPR": "x1",
|
||||
"defaultLanguage": "zh",
|
||||
"defaultCountry": "CN",
|
||||
"themes": {
|
||||
"default": {
|
||||
"activedSystemBar": "system_bar",
|
||||
"activedBottomSystemBar": "system_bar_b",
|
||||
"packaged": true,
|
||||
"fonts": {
|
||||
"default": {
|
||||
"text": " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~,。?!确定取消"
|
||||
}
|
||||
},
|
||||
"lcd": {
|
||||
"width": "320",
|
||||
"height": "480",
|
||||
"colorDepth": "16bit",
|
||||
"colorFormat": "BGR(A)"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"creator": {
|
||||
"name": "AWTK Designer",
|
||||
"version": "2.0.21"
|
||||
},
|
||||
"awtkRoot": "${AWTK_SDK_PATH}/awtk",
|
||||
"dependencies": {
|
||||
"awtk": ">=2112"
|
||||
}
|
||||
}
|
2
lib/awtk/awtk-examples/Moto_A58/3rd/awtk-widget-qr/scripts/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
__pycache__
|
||||
*.pyc
|
@ -0,0 +1,7 @@
|
||||
import os
|
||||
import sys
|
||||
APP_SCRIPTS_ROOT = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
print('APP_SCRIPTS_ROOT:' + APP_SCRIPTS_ROOT)
|
||||
|
||||
sys.path.insert(0, APP_SCRIPTS_ROOT)
|
@ -0,0 +1,7 @@
|
||||
import awtk_locator as locator
|
||||
|
||||
def Helper(ARGUMENTS):
|
||||
locator.init(ARGUMENTS)
|
||||
|
||||
from app_helper_base import AppHelperBase
|
||||
return AppHelperBase(ARGUMENTS)
|
@ -0,0 +1,62 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
AWTK_ROOT = ''
|
||||
|
||||
def getAwtkRoot():
|
||||
return AWTK_ROOT
|
||||
|
||||
def getAwtkSDKPath():
|
||||
env = os.environ
|
||||
if 'AWTK_SDK_PATH' in env:
|
||||
return env['AWTK_SDK_PATH']
|
||||
else:
|
||||
return ''
|
||||
|
||||
def getAwtkOrAwtkLinuxFbRoot(is_linux_fb):
|
||||
if is_linux_fb:
|
||||
return locateAWTK('awtk-linux-fb')
|
||||
else:
|
||||
return locateAWTK('awtk')
|
||||
|
||||
def locateAWTK(awtk):
|
||||
awtk_root = ''
|
||||
|
||||
if not os.path.exists(awtk_root):
|
||||
dirnames = ['../'+awtk, '../../'+awtk, '../../../'+awtk]
|
||||
for dirname in dirnames:
|
||||
if os.path.exists(dirname):
|
||||
awtk_root = dirname
|
||||
break
|
||||
|
||||
if not os.path.exists(awtk_root):
|
||||
awtk_sdk_path = getAwtkSDKPath();
|
||||
if os.path.exists(awtk_sdk_path):
|
||||
awtk_root = awtk_sdk_path + '/' + awtk
|
||||
|
||||
return os.path.abspath(awtk_root)
|
||||
|
||||
def init(ARGUMENTS = None):
|
||||
global AWTK_ROOT
|
||||
global LINUX_FB
|
||||
|
||||
if ARGUMENTS:
|
||||
AWTK_ROOT = ARGUMENTS.get('AWTK_ROOT', '')
|
||||
LINUX_FB = ARGUMENTS.get('LINUX_FB', '')
|
||||
else:
|
||||
LINUX_FB = ''
|
||||
|
||||
if not os.path.exists(AWTK_ROOT):
|
||||
AWTK_ROOT = getAwtkOrAwtkLinuxFbRoot(LINUX_FB != '')
|
||||
elif os.path.exists(LINUX_FB):
|
||||
print(' do not set LINUX_FB and AWTK_ROOT !!!')
|
||||
sys.exit()
|
||||
|
||||
if LINUX_FB:
|
||||
AWTK_SCRIPTS_ROOT = os.path.join(AWTK_ROOT, '../awtk/scripts')
|
||||
else:
|
||||
AWTK_SCRIPTS_ROOT = os.path.join(AWTK_ROOT, 'scripts')
|
||||
sys.path.insert(0, AWTK_SCRIPTS_ROOT)
|
||||
|
||||
print('AWTK_ROOT: ' + AWTK_ROOT)
|
||||
print('AWTK_SCRIPTS_ROOT: ' + AWTK_SCRIPTS_ROOT)
|
@ -0,0 +1,41 @@
|
||||
import sys
|
||||
import awtk_locator as locator
|
||||
|
||||
LONGSOPTS = ['awtk_root=', 'AWTK_ROOT=']
|
||||
def get_args(args, longsopts = []) :
|
||||
list_opts = []
|
||||
for arg in args:
|
||||
if arg.startswith('--') :
|
||||
tmp_opt = '';
|
||||
for opt in longsopts:
|
||||
if arg.find(opt) > 0 :
|
||||
tmp_opt = opt;
|
||||
break
|
||||
if tmp_opt != '' :
|
||||
list_opts.append(arg.split(tmp_opt)[1])
|
||||
continue
|
||||
else :
|
||||
print(arg + " not find command, command :")
|
||||
print(longsopts)
|
||||
sys.exit()
|
||||
return list_opts
|
||||
|
||||
|
||||
def update_res(ARGUMENTS, is_new_usage):
|
||||
locator.init(ARGUMENTS)
|
||||
|
||||
import update_res_app as updater
|
||||
if is_new_usage and not hasattr(updater, "getopt") :
|
||||
print(" must update awtk !!!")
|
||||
sys.exit()
|
||||
updater.run(locator.getAwtkRoot())
|
||||
|
||||
is_new_usage = False
|
||||
opts = get_args(sys.argv[1:], LONGSOPTS)
|
||||
ARGUMENTS = dict()
|
||||
if len(opts) > 0 :
|
||||
is_new_usage = True
|
||||
ARGUMENTS['AWTK_ROOT'] = opts[0]
|
||||
else :
|
||||
ARGUMENTS['AWTK_ROOT'] = ''
|
||||
update_res(ARGUMENTS, is_new_usage)
|
@ -0,0 +1,22 @@
|
||||
import os
|
||||
import sys
|
||||
import platform
|
||||
|
||||
OS_NAME = platform.system();
|
||||
LIB_DIR=os.environ['LIB_DIR'];
|
||||
BIN_DIR=os.environ['BIN_DIR'];
|
||||
|
||||
env=DefaultEnvironment().Clone()
|
||||
SOURCES=Glob('qr/*.cpp') + Glob('qr/*.c') + Glob('*.c')
|
||||
|
||||
EXPORT_DEF=''
|
||||
if OS_NAME == 'Windows' and os.environ['TOOLS_NAME'] == '':
|
||||
EXPORT_DEF = ' /DEF:"src/qr.def" '
|
||||
|
||||
if 'BUILD_SHARED' in os.environ and os.environ['BUILD_SHARED'] == 'True':
|
||||
LIBS=['awtk'];
|
||||
LINKFLAGS=env['LINKFLAGS'] + EXPORT_DEF
|
||||
env.SharedLibrary(os.path.join(BIN_DIR, 'qr'), SOURCES, LIBS=LIBS, LINKFLAGS=LINKFLAGS);
|
||||
else:
|
||||
env.Library(os.path.join(LIB_DIR, 'qr'), SOURCES);
|
||||
|
@ -0,0 +1,8 @@
|
||||
LIBRARY qr
|
||||
EXPORTS
|
||||
qr_register
|
||||
qr_supported_render_mode
|
||||
qr_create
|
||||
qr_cast
|
||||
new_qr_set_value
|
||||
qr_get_widget_vtable
|
@ -0,0 +1,229 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Binary sequence class.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bitstream.h"
|
||||
|
||||
#define DEFAULT_BUFSIZE (128)
|
||||
|
||||
BitStream *BitStream_new(void)
|
||||
{
|
||||
BitStream *bstream;
|
||||
|
||||
bstream = (BitStream *)TKMEM_ALLOC(sizeof(BitStream));
|
||||
if(bstream == NULL) return NULL;
|
||||
|
||||
bstream->length = 0;
|
||||
bstream->data = (unsigned char *)TKMEM_ALLOC(DEFAULT_BUFSIZE);
|
||||
if(bstream->data == NULL) {
|
||||
tk_free(bstream);
|
||||
return NULL;
|
||||
}
|
||||
bstream->datasize = DEFAULT_BUFSIZE;
|
||||
|
||||
return bstream;
|
||||
}
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
BitStream *BitStream_newWithBits(size_t size, unsigned char *bits)
|
||||
{
|
||||
BitStream *bstream;
|
||||
|
||||
if(size == 0) return BitStream_new();
|
||||
|
||||
bstream = (BitStream *)TKMEM_ALLOC(sizeof(BitStream));
|
||||
if(bstream == NULL) return NULL;
|
||||
|
||||
bstream->data = (unsigned char *)TKMEM_ALLOC(size);
|
||||
if(bstream->data == NULL) {
|
||||
tk_free(bstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bstream->length = size;
|
||||
bstream->datasize = size;
|
||||
memcpy(bstream->data, bits, size);
|
||||
|
||||
return bstream;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int BitStream_expand(BitStream *bstream)
|
||||
{
|
||||
unsigned char *data;
|
||||
|
||||
data = (unsigned char *)TKMEM_REALLOC(bstream->data, bstream->datasize * 2);
|
||||
if(data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bstream->data = data;
|
||||
bstream->datasize *= 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void BitStream_writeNum(unsigned char *dest, size_t bits, unsigned int num)
|
||||
{
|
||||
unsigned int mask;
|
||||
size_t i;
|
||||
unsigned char *p;
|
||||
|
||||
p = dest;
|
||||
mask = 1U << (bits - 1);
|
||||
for(i = 0; i < bits; i++) {
|
||||
if(num & mask) {
|
||||
*p = 1;
|
||||
} else {
|
||||
*p = 0;
|
||||
}
|
||||
p++;
|
||||
mask = mask >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void BitStream_writeBytes(unsigned char *dest, size_t size, unsigned char *data)
|
||||
{
|
||||
unsigned char mask;
|
||||
size_t i, j;
|
||||
unsigned char *p;
|
||||
|
||||
p = dest;
|
||||
for(i = 0; i < size; i++) {
|
||||
mask = 0x80;
|
||||
for(j = 0; j < 8; j++) {
|
||||
if(data[i] & mask) {
|
||||
*p = 1;
|
||||
} else {
|
||||
*p = 0;
|
||||
}
|
||||
p++;
|
||||
mask = mask >> 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int BitStream_append(BitStream *bstream, BitStream *arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(arg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if(arg->length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(bstream->length + arg->length > bstream->datasize) {
|
||||
ret = BitStream_expand(bstream);
|
||||
if(ret < 0) return ret;
|
||||
}
|
||||
|
||||
memcpy(bstream->data + bstream->length, arg->data, arg->length);
|
||||
bstream->length += arg->length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BitStream_appendNum(BitStream *bstream, size_t bits, unsigned int num)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(bits == 0) return 0;
|
||||
|
||||
while(bstream->datasize - bstream->length < bits) {
|
||||
ret = BitStream_expand(bstream);
|
||||
if(ret < 0) return ret;
|
||||
}
|
||||
BitStream_writeNum(bstream->data + bstream->length, bits, num);
|
||||
bstream->length += bits;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BitStream_appendBytes(BitStream *bstream, size_t size, unsigned char *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(size == 0) return 0;
|
||||
|
||||
while(bstream->datasize - bstream->length < size * 8) {
|
||||
ret = BitStream_expand(bstream);
|
||||
if(ret < 0) return ret;
|
||||
}
|
||||
BitStream_writeBytes(bstream->data + bstream->length, size, data);
|
||||
bstream->length += size * 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char *BitStream_toByte(BitStream *bstream)
|
||||
{
|
||||
size_t i, j, size, bytes, oddbits;
|
||||
unsigned char *data, v;
|
||||
unsigned char *p;
|
||||
|
||||
size = BitStream_size(bstream);
|
||||
if(size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
data = (unsigned char *)TKMEM_ALLOC((size + 7) / 8);
|
||||
if(data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bytes = size / 8;
|
||||
|
||||
p = bstream->data;
|
||||
for(i = 0; i < bytes; i++) {
|
||||
v = 0;
|
||||
for(j = 0; j < 8; j++) {
|
||||
v = (unsigned char)(v << 1);
|
||||
v |= *p;
|
||||
p++;
|
||||
}
|
||||
data[i] = v;
|
||||
}
|
||||
oddbits = size & 7;
|
||||
if(oddbits > 0) {
|
||||
v = 0;
|
||||
for(j = 0; j < oddbits; j++) {
|
||||
v = (unsigned char)(v << 1);
|
||||
v |= *p;
|
||||
p++;
|
||||
}
|
||||
data[bytes] = (unsigned char)(v << (8 - oddbits));
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void BitStream_free(BitStream *bstream)
|
||||
{
|
||||
if(bstream != NULL) {
|
||||
tk_free(bstream->data);
|
||||
tk_free(bstream);
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Binary sequence class.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef BITSTREAM_H
|
||||
#define BITSTREAM_H
|
||||
|
||||
typedef struct {
|
||||
size_t length;
|
||||
size_t datasize;
|
||||
unsigned char *data;
|
||||
} BitStream;
|
||||
|
||||
extern BitStream *BitStream_new(void);
|
||||
#ifdef WITH_TESTS
|
||||
extern BitStream *BitStream_newWithBits(size_t size, unsigned char *bits);
|
||||
#endif
|
||||
extern int BitStream_append(BitStream *bstream, BitStream *arg);
|
||||
extern int BitStream_appendNum(BitStream *bstream, size_t bits, unsigned int num);
|
||||
extern int BitStream_appendBytes(BitStream *bstream, size_t size, unsigned char *data);
|
||||
#define BitStream_size(__bstream__) (__bstream__->length)
|
||||
#define BitStream_reset(__bstream__) (__bstream__->length = 0)
|
||||
extern unsigned char *BitStream_toByte(BitStream *bstream);
|
||||
extern void BitStream_free(BitStream *bstream);
|
||||
|
||||
#endif /* BITSTREAM_H */
|
@ -0,0 +1,13 @@
|
||||
#ifndef QRENCODER_CONFIG_H
|
||||
#define QRENCODER_CONFIG_H
|
||||
|
||||
#include "awtk.h"
|
||||
#include "tkc/mem.h"
|
||||
|
||||
#define STATIC_IN_RELEASE static
|
||||
#define MAJOR_VERSION 4
|
||||
#define MINOR_VERSION 1
|
||||
#define MICRO_VERSION 0
|
||||
#define VERSION "1.0"
|
||||
|
||||
#endif/*QRENCODER_CONFIG_H*/
|
354
lib/awtk/awtk-examples/Moto_A58/3rd/awtk-widget-qr/src/qr/mask.c
Normal file
@ -0,0 +1,354 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Masking.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "qrencode.h"
|
||||
#include "qrspec.h"
|
||||
#include "mask.h"
|
||||
|
||||
STATIC_IN_RELEASE int Mask_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level)
|
||||
{
|
||||
unsigned int format;
|
||||
unsigned char v;
|
||||
int i;
|
||||
int blacks = 0;
|
||||
|
||||
format = QRspec_getFormatInfo(mask, level);
|
||||
|
||||
for(i = 0; i < 8; i++) {
|
||||
if(format & 1) {
|
||||
blacks += 2;
|
||||
v = 0x85;
|
||||
} else {
|
||||
v = 0x84;
|
||||
}
|
||||
frame[width * 8 + width - 1 - i] = v;
|
||||
if(i < 6) {
|
||||
frame[width * i + 8] = v;
|
||||
} else {
|
||||
frame[width * (i + 1) + 8] = v;
|
||||
}
|
||||
format= format >> 1;
|
||||
}
|
||||
for(i = 0; i < 7; i++) {
|
||||
if(format & 1) {
|
||||
blacks += 2;
|
||||
v = 0x85;
|
||||
} else {
|
||||
v = 0x84;
|
||||
}
|
||||
frame[width * (width - 7 + i) + 8] = v;
|
||||
if(i == 0) {
|
||||
frame[width * 8 + 7] = v;
|
||||
} else {
|
||||
frame[width * 8 + 6 - i] = v;
|
||||
}
|
||||
format= format >> 1;
|
||||
}
|
||||
|
||||
return blacks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Demerit coefficients.
|
||||
* See Section 8.8.2, pp.45, JIS X0510:2004.
|
||||
*/
|
||||
#define N1 (3)
|
||||
#define N2 (3)
|
||||
#define N3 (40)
|
||||
#define N4 (10)
|
||||
|
||||
#define MASKMAKER(__exp__) \
|
||||
int x, y;\
|
||||
int b = 0;\
|
||||
\
|
||||
for(y = 0; y < width; y++) {\
|
||||
for(x = 0; x < width; x++) {\
|
||||
if(*s & 0x80) {\
|
||||
*d = *s;\
|
||||
} else {\
|
||||
*d = *s ^ ((__exp__) == 0);\
|
||||
}\
|
||||
b += (int)(*d & 1);\
|
||||
s++; d++;\
|
||||
}\
|
||||
}\
|
||||
return b;
|
||||
|
||||
static int Mask_mask0(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((x+y)&1)
|
||||
}
|
||||
|
||||
static int Mask_mask1(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(y&1)
|
||||
}
|
||||
|
||||
static int Mask_mask2(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(x%3)
|
||||
}
|
||||
|
||||
static int Mask_mask3(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((x+y)%3)
|
||||
}
|
||||
|
||||
static int Mask_mask4(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(((y/2)+(x/3))&1)
|
||||
}
|
||||
|
||||
static int Mask_mask5(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(((x*y)&1)+(x*y)%3)
|
||||
}
|
||||
|
||||
static int Mask_mask6(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((((x*y)&1)+(x*y)%3)&1)
|
||||
}
|
||||
|
||||
static int Mask_mask7(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((((x*y)%3)+((x+y)&1))&1)
|
||||
}
|
||||
|
||||
#define maskNum (8)
|
||||
typedef int MaskMaker(int, const unsigned char *, unsigned char *);
|
||||
static MaskMaker *maskMakers[maskNum] = {
|
||||
Mask_mask0, Mask_mask1, Mask_mask2, Mask_mask3,
|
||||
Mask_mask4, Mask_mask5, Mask_mask6, Mask_mask7
|
||||
};
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
unsigned char *Mask_makeMaskedFrame(int width, unsigned char *frame, int mask)
|
||||
{
|
||||
unsigned char *masked;
|
||||
|
||||
masked = (unsigned char *)TKMEM_ALLOC((size_t)(width * width));
|
||||
if(masked == NULL) return NULL;
|
||||
|
||||
maskMakers[mask](width, frame, masked);
|
||||
|
||||
return masked;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned char *Mask_makeMask(int width, unsigned char *frame, int mask, QRecLevel level)
|
||||
{
|
||||
unsigned char *masked;
|
||||
|
||||
if(mask < 0 || mask >= maskNum) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
masked = (unsigned char *)TKMEM_ALLOC((size_t)(width * width));
|
||||
if(masked == NULL) return NULL;
|
||||
|
||||
maskMakers[mask](width, frame, masked);
|
||||
Mask_writeFormatInformation(width, masked, mask, level);
|
||||
|
||||
return masked;
|
||||
}
|
||||
|
||||
|
||||
//static int n1;
|
||||
//static int n2;
|
||||
//static int n3;
|
||||
//static int n4;
|
||||
|
||||
STATIC_IN_RELEASE int Mask_calcN1N3(int length, int *runLength)
|
||||
{
|
||||
int i;
|
||||
int demerit = 0;
|
||||
int fact;
|
||||
|
||||
for(i = 0; i < length; i++) {
|
||||
if(runLength[i] >= 5) {
|
||||
demerit += N1 + (runLength[i] - 5);
|
||||
//n1 += N1 + (runLength[i] - 5);
|
||||
}
|
||||
if((i & 1)) {
|
||||
if(i >= 3 && i < length-2 && (runLength[i] % 3) == 0) {
|
||||
fact = runLength[i] / 3;
|
||||
if(runLength[i-2] == fact &&
|
||||
runLength[i-1] == fact &&
|
||||
runLength[i+1] == fact &&
|
||||
runLength[i+2] == fact) {
|
||||
if(i == 3 || runLength[i-3] >= 4 * fact) {
|
||||
demerit += N3;
|
||||
//n3 += N3;
|
||||
} else if(i+4 >= length || runLength[i+3] >= 4 * fact) {
|
||||
demerit += N3;
|
||||
//n3 += N3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return demerit;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE int Mask_calcN2(int width, unsigned char *frame)
|
||||
{
|
||||
int x, y;
|
||||
unsigned char *p;
|
||||
unsigned char b22, w22;
|
||||
int demerit = 0;
|
||||
|
||||
p = frame + width + 1;
|
||||
for(y = 1; y < width; y++) {
|
||||
for(x = 1; x < width; x++) {
|
||||
b22 = p[0] & p[-1] & p[-width] & p [-width-1];
|
||||
w22 = p[0] | p[-1] | p[-width] | p [-width-1];
|
||||
if((b22 | (w22 ^ 1))&1) {
|
||||
demerit += N2;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
return demerit;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE int Mask_calcRunLengthH(int width, unsigned char *frame, int *runLength)
|
||||
{
|
||||
int head;
|
||||
int i;
|
||||
unsigned char prev;
|
||||
|
||||
if(frame[0] & 1) {
|
||||
runLength[0] = -1;
|
||||
head = 1;
|
||||
} else {
|
||||
head = 0;
|
||||
}
|
||||
runLength[head] = 1;
|
||||
prev = frame[0];
|
||||
|
||||
for(i = 1; i < width; i++) {
|
||||
if((frame[i] ^ prev) & 1) {
|
||||
head++;
|
||||
runLength[head] = 1;
|
||||
prev = frame[i];
|
||||
} else {
|
||||
runLength[head]++;
|
||||
}
|
||||
}
|
||||
|
||||
return head + 1;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE int Mask_calcRunLengthV(int width, unsigned char *frame, int *runLength)
|
||||
{
|
||||
int head;
|
||||
int i;
|
||||
unsigned char prev;
|
||||
|
||||
if(frame[0] & 1) {
|
||||
runLength[0] = -1;
|
||||
head = 1;
|
||||
} else {
|
||||
head = 0;
|
||||
}
|
||||
runLength[head] = 1;
|
||||
prev = frame[0];
|
||||
|
||||
for(i = 1; i < width; i++) {
|
||||
if((frame[i * width] ^ prev) & 1) {
|
||||
head++;
|
||||
runLength[head] = 1;
|
||||
prev = frame[i * width];
|
||||
} else {
|
||||
runLength[head]++;
|
||||
}
|
||||
}
|
||||
|
||||
return head + 1;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE int Mask_evaluateSymbol(int width, unsigned char *frame)
|
||||
{
|
||||
int x, y;
|
||||
int demerit = 0;
|
||||
int runLength[QRSPEC_WIDTH_MAX + 1];
|
||||
int length;
|
||||
|
||||
demerit += Mask_calcN2(width, frame);
|
||||
|
||||
for(y = 0; y < width; y++) {
|
||||
length = Mask_calcRunLengthH(width, frame + y * width, runLength);
|
||||
demerit += Mask_calcN1N3(length, runLength);
|
||||
}
|
||||
|
||||
for(x = 0; x < width; x++) {
|
||||
length = Mask_calcRunLengthV(width, frame + x, runLength);
|
||||
demerit += Mask_calcN1N3(length, runLength);
|
||||
}
|
||||
|
||||
return demerit;
|
||||
}
|
||||
|
||||
unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level)
|
||||
{
|
||||
int i;
|
||||
unsigned char *mask, *bestMask;
|
||||
int minDemerit = INT_MAX;
|
||||
int blacks;
|
||||
int bratio;
|
||||
int demerit;
|
||||
int w2 = width * width;
|
||||
|
||||
mask = (unsigned char *)TKMEM_ALLOC((size_t)w2);
|
||||
if(mask == NULL) return NULL;
|
||||
bestMask = (unsigned char *)TKMEM_ALLOC((size_t)w2);
|
||||
if(bestMask == NULL) {
|
||||
tk_free(mask);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < maskNum; i++) {
|
||||
// n1 = n2 = n3 = n4 = 0;
|
||||
demerit = 0;
|
||||
blacks = maskMakers[i](width, frame, mask);
|
||||
blacks += Mask_writeFormatInformation(width, mask, i, level);
|
||||
bratio = (200 * blacks + w2) / w2 / 2; /* (int)(100*blacks/w2+0.5) */
|
||||
demerit = (abs(bratio - 50) / 5) * N4;
|
||||
// n4 = demerit;
|
||||
demerit += Mask_evaluateSymbol(width, mask);
|
||||
// printf("(%d,%d,%d,%d)=%d\n", n1, n2, n3 ,n4, demerit);
|
||||
if(demerit < minDemerit) {
|
||||
minDemerit = demerit;
|
||||
memcpy(bestMask, mask, (size_t)w2);
|
||||
}
|
||||
}
|
||||
tk_free(mask);
|
||||
return bestMask;
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Masking.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MASK_H
|
||||
#define MASK_H
|
||||
|
||||
extern unsigned char *Mask_makeMask(int width, unsigned char *frame, int mask, QRecLevel level);
|
||||
extern unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level);
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
extern int Mask_calcN2(int width, unsigned char *frame);
|
||||
extern int Mask_calcN1N3(int length, int *runLength);
|
||||
extern int Mask_calcRunLengthH(int width, unsigned char *frame, int *runLength);
|
||||
extern int Mask_calcRunLengthV(int width, unsigned char *frame, int *runLength);
|
||||
extern int Mask_evaluateSymbol(int width, unsigned char *frame);
|
||||
extern int Mask_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level);
|
||||
extern unsigned char *Mask_makeMaskedFrame(int width, unsigned char *frame, int mask);
|
||||
#endif
|
||||
|
||||
#endif /* MASK_H */
|
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Masking for Micro QR Code.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "qrencode.h"
|
||||
#include "mqrspec.h"
|
||||
#include "mmask.h"
|
||||
|
||||
STATIC_IN_RELEASE void MMask_writeFormatInformation(int version, int width, unsigned char *frame, int mask, QRecLevel level)
|
||||
{
|
||||
unsigned int format;
|
||||
unsigned char v;
|
||||
int i;
|
||||
|
||||
format = MQRspec_getFormatInfo(mask, version, level);
|
||||
|
||||
for(i = 0; i < 8; i++) {
|
||||
v = 0x84 | (format & 1);
|
||||
frame[width * (i + 1) + 8] = v;
|
||||
format = format >> 1;
|
||||
}
|
||||
for(i = 0; i < 7; i++) {
|
||||
v = 0x84 | (format & 1);
|
||||
frame[width * 8 + 7 - i] = v;
|
||||
format = format >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
#define MASKMAKER(__exp__) \
|
||||
int x, y;\
|
||||
\
|
||||
for(y = 0; y < width; y++) {\
|
||||
for(x = 0; x < width; x++) {\
|
||||
if(*s & 0x80) {\
|
||||
*d = *s;\
|
||||
} else {\
|
||||
*d = *s ^ ((__exp__) == 0);\
|
||||
}\
|
||||
s++; d++;\
|
||||
}\
|
||||
}
|
||||
|
||||
static void Mask_mask0(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(y&1)
|
||||
}
|
||||
|
||||
static void Mask_mask1(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(((y/2)+(x/3))&1)
|
||||
}
|
||||
|
||||
static void Mask_mask2(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((((x*y)&1)+(x*y)%3)&1)
|
||||
}
|
||||
|
||||
static void Mask_mask3(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((((x+y)&1)+((x*y)%3))&1)
|
||||
}
|
||||
|
||||
#define maskNum (4)
|
||||
typedef void MaskMaker(int, const unsigned char *, unsigned char *);
|
||||
static MaskMaker *maskMakers[maskNum] = {
|
||||
Mask_mask0, Mask_mask1, Mask_mask2, Mask_mask3
|
||||
};
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
unsigned char *MMask_makeMaskedFrame(int width, unsigned char *frame, int mask)
|
||||
{
|
||||
unsigned char *masked;
|
||||
|
||||
masked = (unsigned char *)TKMEM_ALLOC((size_t)(width * width));
|
||||
if(masked == NULL) return NULL;
|
||||
|
||||
maskMakers[mask](width, frame, masked);
|
||||
|
||||
return masked;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned char *MMask_makeMask(int version, unsigned char *frame, int mask, QRecLevel level)
|
||||
{
|
||||
unsigned char *masked;
|
||||
int width;
|
||||
|
||||
if(mask < 0 || mask >= maskNum) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
width = MQRspec_getWidth(version);
|
||||
masked = (unsigned char *)TKMEM_ALLOC((size_t)(width * width));
|
||||
if(masked == NULL) return NULL;
|
||||
|
||||
maskMakers[mask](width, frame, masked);
|
||||
MMask_writeFormatInformation(version, width, masked, mask, level);
|
||||
|
||||
return masked;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE int MMask_evaluateSymbol(int width, unsigned char *frame)
|
||||
{
|
||||
int x, y;
|
||||
unsigned char *p;
|
||||
int sum1 = 0, sum2 = 0;
|
||||
|
||||
p = frame + width * (width - 1);
|
||||
for(x = 1; x < width; x++) {
|
||||
sum1 += (p[x] & 1);
|
||||
}
|
||||
|
||||
p = frame + width * 2 - 1;
|
||||
for(y = 1; y < width; y++) {
|
||||
sum2 += (*p & 1);
|
||||
p += width;
|
||||
}
|
||||
|
||||
return (sum1 <= sum2)?(sum1 * 16 + sum2):(sum2 * 16 + sum1);
|
||||
}
|
||||
|
||||
unsigned char *MMask_mask(int version, unsigned char *frame, QRecLevel level)
|
||||
{
|
||||
int i;
|
||||
unsigned char *mask, *bestMask;
|
||||
int maxScore = 0;
|
||||
int score;
|
||||
int width;
|
||||
|
||||
width = MQRspec_getWidth(version);
|
||||
|
||||
mask = (unsigned char *)TKMEM_ALLOC((size_t)(width * width));
|
||||
if(mask == NULL) return NULL;
|
||||
bestMask = NULL;
|
||||
|
||||
for(i = 0; i < maskNum; i++) {
|
||||
score = 0;
|
||||
maskMakers[i](width, frame, mask);
|
||||
MMask_writeFormatInformation(version, width, mask, i, level);
|
||||
score = MMask_evaluateSymbol(width, mask);
|
||||
if(score > maxScore) {
|
||||
maxScore = score;
|
||||
tk_free(bestMask);
|
||||
bestMask = mask;
|
||||
mask = (unsigned char *)TKMEM_ALLOC((size_t)(width * width));
|
||||
if(mask == NULL) break;
|
||||
}
|
||||
}
|
||||
tk_free(mask);
|
||||
return bestMask;
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Masking for Micro QR Code.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MMASK_H
|
||||
#define MMASK_H
|
||||
|
||||
extern unsigned char *MMask_makeMask(int version, unsigned char *frame, int mask, QRecLevel level);
|
||||
extern unsigned char *MMask_mask(int version, unsigned char *frame, QRecLevel level);
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
extern int MMask_evaluateSymbol(int width, unsigned char *frame);
|
||||
extern void MMask_writeFormatInformation(int version, int width, unsigned char *frame, int mask, QRecLevel level);
|
||||
extern unsigned char *MMask_makeMaskedFrame(int width, unsigned char *frame, int mask);
|
||||
#endif
|
||||
|
||||
#endif /* MMASK_H */
|
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Micro QR Code specification in convenient format.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* The following data / specifications are taken from
|
||||
* "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
|
||||
* or
|
||||
* "Automatic identification and data capture techniques --
|
||||
* QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "mqrspec.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Version and capacity
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
int width; ///< Edge length of the symbol
|
||||
int ec[4]; ///< Number of ECC code (bytes)
|
||||
} MQRspec_Capacity;
|
||||
|
||||
/**
|
||||
* Table of the capacity of symbols
|
||||
* See Table 1 (pp.106) and Table 8 (pp.113) of Appendix 1, JIS X0510:2004.
|
||||
*/
|
||||
static const MQRspec_Capacity mqrspecCapacity[MQRSPEC_VERSION_MAX + 1] = {
|
||||
{ 0, {0, 0, 0, 0}},
|
||||
{ 11, {2, 0, 0, 0}},
|
||||
{ 13, {5, 6, 0, 0}},
|
||||
{ 15, {6, 8, 0, 0}},
|
||||
{ 17, {8, 10, 14, 0}}
|
||||
};
|
||||
|
||||
int MQRspec_getDataLengthBit(int version, QRecLevel level)
|
||||
{
|
||||
int w;
|
||||
int ecc;
|
||||
|
||||
w = mqrspecCapacity[version].width - 1;
|
||||
ecc = mqrspecCapacity[version].ec[level];
|
||||
if(ecc == 0) return 0;
|
||||
return w * w - 64 - ecc * 8;
|
||||
}
|
||||
|
||||
int MQRspec_getDataLength(int version, QRecLevel level)
|
||||
{
|
||||
return (MQRspec_getDataLengthBit(version, level) + 4) / 8;
|
||||
}
|
||||
|
||||
int MQRspec_getECCLength(int version, QRecLevel level)
|
||||
{
|
||||
return mqrspecCapacity[version].ec[level];
|
||||
}
|
||||
|
||||
int MQRspec_getWidth(int version)
|
||||
{
|
||||
return mqrspecCapacity[version].width;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Length indicator
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* See Table 3 (pp.107) of Appendix 1, JIS X0510:2004.
|
||||
*/
|
||||
static const int lengthTableBits[4][4] = {
|
||||
{ 3, 4, 5, 6},
|
||||
{ 0, 3, 4, 5},
|
||||
{ 0, 0, 4, 5},
|
||||
{ 0, 0, 3, 4}
|
||||
};
|
||||
|
||||
int MQRspec_lengthIndicator(QRencodeMode mode, int version)
|
||||
{
|
||||
return lengthTableBits[mode][version - 1];
|
||||
}
|
||||
|
||||
int MQRspec_maximumWords(QRencodeMode mode, int version)
|
||||
{
|
||||
int bits;
|
||||
int words;
|
||||
|
||||
bits = lengthTableBits[mode][version - 1];
|
||||
words = (1 << bits) - 1;
|
||||
if(mode == QR_MODE_KANJI) {
|
||||
words *= 2; // the number of bytes is required
|
||||
}
|
||||
|
||||
return words;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Format information
|
||||
*****************************************************************************/
|
||||
|
||||
/* See calcFormatInfo in tests/test_mqrspec.c */
|
||||
static const unsigned int formatInfo[4][8] = {
|
||||
{0x4445, 0x55ae, 0x6793, 0x7678, 0x06de, 0x1735, 0x2508, 0x34e3},
|
||||
{0x4172, 0x5099, 0x62a4, 0x734f, 0x03e9, 0x1202, 0x203f, 0x31d4},
|
||||
{0x4e2b, 0x5fc0, 0x6dfd, 0x7c16, 0x0cb0, 0x1d5b, 0x2f66, 0x3e8d},
|
||||
{0x4b1c, 0x5af7, 0x68ca, 0x7921, 0x0987, 0x186c, 0x2a51, 0x3bba}
|
||||
};
|
||||
|
||||
/* See Table 10 of Appendix 1. (pp.115) */
|
||||
static const int typeTable[MQRSPEC_VERSION_MAX + 1][3] = {
|
||||
{-1, -1, -1},
|
||||
{ 0, -1, -1},
|
||||
{ 1, 2, -1},
|
||||
{ 3, 4, -1},
|
||||
{ 5, 6, 7}
|
||||
};
|
||||
|
||||
unsigned int MQRspec_getFormatInfo(int mask, int version, QRecLevel level)
|
||||
{
|
||||
int type;
|
||||
|
||||
if(mask < 0 || mask > 3) return 0;
|
||||
if(version <= 0 || version > MQRSPEC_VERSION_MAX) return 0;
|
||||
if(level == QR_ECLEVEL_H) return 0;
|
||||
type = typeTable[version][level];
|
||||
if(type < 0) return 0;
|
||||
|
||||
return formatInfo[mask][type];
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Frame
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Put a finder pattern.
|
||||
* @param frame
|
||||
* @param width
|
||||
* @param ox,oy upper-left coordinate of the pattern
|
||||
*/
|
||||
static void putFinderPattern(unsigned char *frame, int width, int ox, int oy)
|
||||
{
|
||||
static const unsigned char finder[] = {
|
||||
0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
|
||||
0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
|
||||
0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
|
||||
0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
|
||||
0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
|
||||
0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
|
||||
0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
|
||||
};
|
||||
int x, y;
|
||||
const unsigned char *s;
|
||||
|
||||
frame += oy * width + ox;
|
||||
s = finder;
|
||||
for(y = 0; y < 7; y++) {
|
||||
for(x = 0; x < 7; x++) {
|
||||
frame[x] = s[x];
|
||||
}
|
||||
frame += width;
|
||||
s += 7;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char *MQRspec_createFrame(int version)
|
||||
{
|
||||
unsigned char *frame, *p, *q;
|
||||
int width;
|
||||
int x, y;
|
||||
|
||||
width = mqrspecCapacity[version].width;
|
||||
frame = (unsigned char *)TKMEM_ALLOC((size_t)(width * width));
|
||||
if(frame == NULL) return NULL;
|
||||
|
||||
memset(frame, 0, (size_t)(width * width));
|
||||
/* Finder pattern */
|
||||
putFinderPattern(frame, width, 0, 0);
|
||||
/* Separator */
|
||||
p = frame;
|
||||
for(y = 0; y < 7; y++) {
|
||||
p[7] = 0xc0;
|
||||
p += width;
|
||||
}
|
||||
memset(frame + width * 7, 0xc0, 8);
|
||||
/* Mask format information area */
|
||||
memset(frame + width * 8 + 1, 0x84, 8);
|
||||
p = frame + width + 8;
|
||||
for(y = 0; y < 7; y++) {
|
||||
*p = 0x84;
|
||||
p += width;
|
||||
}
|
||||
/* Timing pattern */
|
||||
p = frame + 8;
|
||||
q = frame + width * 8;
|
||||
for(x = 1; x < width-7; x++) {
|
||||
*p = 0x90 | (x & 1);
|
||||
*q = 0x90 | (x & 1);
|
||||
p++;
|
||||
q += width;
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
unsigned char *MQRspec_newFrame(int version)
|
||||
{
|
||||
if(version < 1 || version > MQRSPEC_VERSION_MAX) return NULL;
|
||||
|
||||
return MQRspec_createFrame(version);
|
||||
}
|
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Micro QR Code specification in convenient format.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MQRSPEC_H
|
||||
#define MQRSPEC_H
|
||||
|
||||
#include "qrencode.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Version and capacity
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Maximum width of a symbol
|
||||
*/
|
||||
#define MQRSPEC_WIDTH_MAX 17
|
||||
|
||||
/**
|
||||
* Return maximum data code length (bits) for the version.
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @return maximum size (bits)
|
||||
*/
|
||||
extern int MQRspec_getDataLengthBit(int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return maximum data code length (bytes) for the version.
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @return maximum size (bytes)
|
||||
*/
|
||||
extern int MQRspec_getDataLength(int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return maximum error correction code length (bytes) for the version.
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @return ECC size (bytes)
|
||||
*/
|
||||
extern int MQRspec_getECCLength(int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return a version number that satisfies the input code length.
|
||||
* @param size input code length (byte)
|
||||
* @param level error correction level
|
||||
* @return version number
|
||||
*/
|
||||
extern int MQRspec_getMinimumVersion(int size, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return the width of the symbol for the version.
|
||||
* @param version version of the symbol
|
||||
* @return width
|
||||
*/
|
||||
extern int MQRspec_getWidth(int version);
|
||||
|
||||
/**
|
||||
* Return the numer of remainder bits.
|
||||
* @param version version of the symbol
|
||||
* @return number of remainder bits
|
||||
*/
|
||||
extern int MQRspec_getRemainder(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Length indicator
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return the size of length indicator for the mode and version.
|
||||
* @param mode encode mode
|
||||
* @param version vesion of the symbol
|
||||
* @return the size of the appropriate length indicator (bits).
|
||||
*/
|
||||
extern int MQRspec_lengthIndicator(QRencodeMode mode, int version);
|
||||
|
||||
/**
|
||||
* Return the maximum length for the mode and version.
|
||||
* @param mode encode mode
|
||||
* @param version vesion of the symbol
|
||||
* @return the maximum length (bytes)
|
||||
*/
|
||||
extern int MQRspec_maximumWords(QRencodeMode mode, int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Version information pattern
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return BCH encoded version information pattern that is used for the symbol
|
||||
* of version 7 or greater. Use lower 18 bits.
|
||||
* @param version vesion of the symbol
|
||||
* @return BCH encoded version information pattern
|
||||
*/
|
||||
extern unsigned int MQRspec_getVersionPattern(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Format information
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return BCH encoded format information pattern.
|
||||
* @param mask mask number
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @return BCH encoded format information pattern
|
||||
*/
|
||||
extern unsigned int MQRspec_getFormatInfo(int mask, int version, QRecLevel level);
|
||||
|
||||
/******************************************************************************
|
||||
* Frame
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return a copy of initialized frame.
|
||||
* @param version version of the symbol
|
||||
* @return Array of unsigned char. You can free it by free().
|
||||
*/
|
||||
extern unsigned char *MQRspec_newFrame(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Mode indicator
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Mode indicator. See Table 2 in Appendix 1 of JIS X0510:2004, pp.107.
|
||||
*/
|
||||
#define MQRSPEC_MODEID_NUM 0
|
||||
#define MQRSPEC_MODEID_AN 1
|
||||
#define MQRSPEC_MODEID_8 2
|
||||
#define MQRSPEC_MODEID_KANJI 3
|
||||
|
||||
#endif /* MQRSPEC_H */
|
214
lib/awtk/awtk-examples/Moto_A58/3rd/awtk-widget-qr/src/qr/qr.c
Normal file
@ -0,0 +1,214 @@
|
||||
/**
|
||||
* File: qr.c
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: 显示二维码的控件
|
||||
*
|
||||
* Copyright (c) 2020 - 2020 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2020-06-01 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tkc/mem.h"
|
||||
#include "tkc/utils.h"
|
||||
#include "base/widget_vtable.h"
|
||||
#include "base/window_manager.h"
|
||||
|
||||
#include "qr.h"
|
||||
|
||||
#define IMAGE_QR_MAX_RATIO 0.45f /* 贴图的面积和二维码的面积最大比例 */
|
||||
|
||||
static ret_t qr_ensure_qrcode(widget_t* widget);
|
||||
|
||||
ret_t new_qr_set_value(widget_t* widget, const char* value) {
|
||||
qr_t* qr = QR(widget);
|
||||
return_value_if_fail(qr != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (tk_str_eq(qr->value, value)) { return RET_OK; }
|
||||
qr->value = tk_str_copy(qr->value, value);
|
||||
|
||||
if (qr->qrcode != NULL) {
|
||||
QRcode_free(qr->qrcode);
|
||||
qr->qrcode = NULL;
|
||||
}
|
||||
|
||||
ret_t ret = qr_ensure_qrcode(widget);
|
||||
return (ret == RET_OK) ? widget_invalidate(widget, NULL) : RET_FAIL;
|
||||
}
|
||||
|
||||
static ret_t qr_get_prop(widget_t* widget, const char* name, value_t* v) {
|
||||
qr_t* qr = QR(widget);
|
||||
return_value_if_fail(qr != NULL && name != NULL && v != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (tk_str_eq(WIDGET_PROP_VALUE, name) || tk_str_eq(WIDGET_PROP_TEXT, name)) {
|
||||
value_set_str(v, qr->value);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
return RET_NOT_FOUND;
|
||||
}
|
||||
|
||||
static ret_t qr_set_prop(widget_t* widget, const char* name, const value_t* v) {
|
||||
qr_t* qr = QR(widget);
|
||||
return_value_if_fail(widget != NULL && name != NULL && v != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (tk_str_eq(WIDGET_PROP_VALUE, name) || tk_str_eq(WIDGET_PROP_TEXT, name)) {
|
||||
new_qr_set_value(widget, value_str(v));
|
||||
|
||||
if (qr->qrcode != NULL) {
|
||||
QRcode_free(qr->qrcode);
|
||||
qr->qrcode = NULL;
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
return RET_NOT_FOUND;
|
||||
}
|
||||
|
||||
static ret_t qr_on_destroy(widget_t* widget) {
|
||||
qr_t* qr = QR(widget);
|
||||
return_value_if_fail(widget != NULL && qr != NULL, RET_BAD_PARAMS);
|
||||
|
||||
TKMEM_FREE(qr->value);
|
||||
if (qr->qrcode != NULL) {
|
||||
QRcode_free(qr->qrcode);
|
||||
qr->qrcode = NULL;
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
#define MIN_SIZE 21
|
||||
|
||||
static ret_t qr_ensure_qrcode(widget_t* widget) {
|
||||
qr_t* qr = QR(widget);
|
||||
int32_t size = tk_min(widget->w, widget->h) - 5;
|
||||
|
||||
if (size < MIN_SIZE) {
|
||||
return RET_FAIL;
|
||||
}
|
||||
|
||||
if (qr->qrcode != NULL) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
qr->qrcode = QRcode_encodeString(qr->value, 3, QR_ECLEVEL_H, QR_MODE_8, 1);
|
||||
|
||||
if (qr->qrcode != NULL) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
return RET_FAIL;
|
||||
}
|
||||
|
||||
static ret_t qr_paint_logo(widget_t* widget, canvas_t* c) {
|
||||
vgcanvas_t* vg = canvas_get_vgcanvas(c);
|
||||
const char* logo_name = NULL;
|
||||
bitmap_t logo = {0};
|
||||
return_value_if_fail(widget != NULL && vg != NULL, RET_BAD_PARAMS);
|
||||
|
||||
logo_name = style_get_str(widget->astyle, STYLE_ID_BG_IMAGE, NULL);
|
||||
|
||||
if (logo_name != NULL && widget_load_image(widget, logo_name, &logo) == RET_OK) {
|
||||
vgcanvas_translate(vg, c->ox + (widget->w - logo.w) / 2.0f,
|
||||
c->oy + (widget->h - logo.h) / 2.0f);
|
||||
vgcanvas_draw_image(vg, &logo, 0, 0, logo.w, logo.h, 0, 0, logo.w, logo.h);
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t qr_on_paint_self(widget_t* widget, canvas_t* c) {
|
||||
qr_t* qr = QR(widget);
|
||||
style_t* style = widget->astyle;
|
||||
|
||||
if (style != NULL) {
|
||||
color_t trans = color_init(0, 0, 0, 0);
|
||||
uint32_t margin = style_get_int(style, STYLE_ID_MARGIN, 2);
|
||||
color_t bg = style_get_color(style, STYLE_ID_BG_COLOR, trans);
|
||||
color_t fg = style_get_color(style, STYLE_ID_FG_COLOR, trans);
|
||||
|
||||
if (qr_ensure_qrcode(widget) == RET_OK) {
|
||||
rect_t r = { 0, 0, widget->w, widget->h };
|
||||
uint32_t w = 0;
|
||||
uint32_t h = 0;
|
||||
uint32_t i = 0;
|
||||
uint32_t j = 0;
|
||||
uint8_t* p = qr->qrcode->data;
|
||||
uint32_t size = qr->qrcode->width;
|
||||
uint32_t pix_size = (tk_min(widget->w, widget->h) - 2 * margin) / size;
|
||||
uint32_t x = (widget->w - pix_size * size) / 2;
|
||||
uint32_t y = (widget->h - pix_size * size) / 2;
|
||||
rect_t r_clip = rect_init(widget->x + ((1 - IMAGE_QR_MAX_RATIO) / 2.0f) * widget->w,
|
||||
widget->y + ((1 - IMAGE_QR_MAX_RATIO) / 2.0f) * widget->h,
|
||||
IMAGE_QR_MAX_RATIO * widget->w, IMAGE_QR_MAX_RATIO * widget->h);
|
||||
|
||||
return_value_if_fail(pix_size > 1, RET_BAD_PARAMS);
|
||||
|
||||
for (j = 0; j < size; j++) {
|
||||
x = (widget->w - pix_size * size) / 2;
|
||||
for (i = 0; i < size; i++) {
|
||||
if (*p & 0x01) {
|
||||
canvas_set_fill_color(c, fg);
|
||||
} else {
|
||||
canvas_set_fill_color(c, bg);
|
||||
}
|
||||
canvas_fill_rect(c, x, y, pix_size, pix_size);
|
||||
p++;
|
||||
x += pix_size;
|
||||
}
|
||||
y += pix_size;
|
||||
}
|
||||
|
||||
widget_paint_with_clip(widget, &r_clip, c, qr_paint_logo);
|
||||
}
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t qr_on_event(widget_t* widget, event_t* e) {
|
||||
qr_t* qr = QR(widget);
|
||||
return_value_if_fail(widget != NULL && qr != NULL, RET_BAD_PARAMS);
|
||||
|
||||
(void)qr;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
const char* s_qr_properties[] = {WIDGET_PROP_VALUE, NULL};
|
||||
|
||||
TK_DECL_VTABLE(qr) = {.size = sizeof(qr_t),
|
||||
.type = WIDGET_TYPE_QR,
|
||||
.clone_properties = s_qr_properties,
|
||||
.persistent_properties = s_qr_properties,
|
||||
.parent = TK_PARENT_VTABLE(widget),
|
||||
.create = qr_create,
|
||||
.on_paint_self = qr_on_paint_self,
|
||||
.set_prop = qr_set_prop,
|
||||
.get_prop = qr_get_prop,
|
||||
.on_event = qr_on_event,
|
||||
.on_destroy = qr_on_destroy};
|
||||
|
||||
widget_t* qr_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
|
||||
widget_t* widget = widget_create(parent, TK_REF_VTABLE(qr), x, y, w, h);
|
||||
qr_t* qr = QR(widget);
|
||||
return_value_if_fail(qr != NULL, NULL);
|
||||
return widget;
|
||||
}
|
||||
|
||||
widget_t* qr_cast(widget_t* widget) {
|
||||
return_value_if_fail(WIDGET_IS_INSTANCE_OF(widget, qr), NULL);
|
||||
|
||||
return widget;
|
||||
}
|
115
lib/awtk/awtk-examples/Moto_A58/3rd/awtk-widget-qr/src/qr/qr.h
Normal file
@ -0,0 +1,115 @@
|
||||
/**
|
||||
* File: qr.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: 显示二维码的控件
|
||||
*
|
||||
* Copyright (c) 2020 - 2020 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2020-06-01 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TK_QR_H
|
||||
#define TK_QR_H
|
||||
#include "qrencode.h"
|
||||
#include "base/widget.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
/**
|
||||
* @class qr_t
|
||||
* @parent widget_t
|
||||
* @annotation ["scriptable","design","widget"]
|
||||
* 显示二维码的控件
|
||||
* qr\_t是[widget\_t](widget_t.md)的子类控件,widget\_t的函数均适用于qr\_t控件。
|
||||
*
|
||||
* 在xml中使用"qr"标签创建数值文本控件。如:
|
||||
*
|
||||
* ```xml
|
||||
* <!-- ui -->
|
||||
* <qr x="c" y="m" w="240" h="240" value="https://github.com/zlgopen/awtk"/>
|
||||
* ```
|
||||
* 在c代码中使用函数qr\_create创建数值文本控件。如:
|
||||
*
|
||||
* ```c
|
||||
* widget_t* qr = qr_create(win, 10, 10, 128, 128);
|
||||
* ```
|
||||
* 可用通过style来设置控件的显示风格,如字体的大小和颜色等等。如:
|
||||
*
|
||||
* ```xml
|
||||
* <!-- style -->
|
||||
* <qr>
|
||||
* <style name="default" >
|
||||
* <normal fg_color="black" bg_color="white" bg_image="message"/>
|
||||
* <disable fg_color="gray" bg_color="#f0f0f0"/>
|
||||
* </style>
|
||||
* </qr>
|
||||
* ```
|
||||
*/
|
||||
typedef struct _qr_t {
|
||||
widget_t widget;
|
||||
|
||||
/**
|
||||
* @property {char*} value
|
||||
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
|
||||
* 要转成二维码的字符串。值。
|
||||
*/
|
||||
char* value;
|
||||
|
||||
/*private*/
|
||||
QRcode* qrcode;
|
||||
} qr_t;
|
||||
|
||||
/**
|
||||
* @method qr_create
|
||||
* @annotation ["constructor", "scriptable"]
|
||||
* 创建qr对象
|
||||
* @param {widget_t*} parent 父控件
|
||||
* @param {xy_t} x x坐标
|
||||
* @param {xy_t} y y坐标
|
||||
* @param {wh_t} w 宽度
|
||||
* @param {wh_t} h 高度
|
||||
*
|
||||
* @return {widget_t*} qr对象。
|
||||
*/
|
||||
widget_t* qr_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
|
||||
/**
|
||||
* @method qr_cast
|
||||
* 转换为qr对象(供脚本语言使用)。
|
||||
* @annotation ["cast", "scriptable"]
|
||||
* @param {widget_t*} widget qr对象。
|
||||
*
|
||||
* @return {widget_t*} qr对象。
|
||||
*/
|
||||
widget_t* qr_cast(widget_t* widget);
|
||||
|
||||
/**
|
||||
* @method new_qr_set_value
|
||||
* 设置要转成二维码的字符串。
|
||||
* @annotation ["scriptable"]
|
||||
* @param {widget_t*} widget widget对象。
|
||||
* @param {const char*} value 格式字符串。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t new_qr_set_value(widget_t* widget, const char* value);
|
||||
|
||||
#define WIDGET_TYPE_QR "qr"
|
||||
#define QR(widget) ((qr_t*)(qr_cast(WIDGET(widget))))
|
||||
|
||||
/*public for subclass and runtime type check*/
|
||||
TK_EXTERN_VTABLE(qr);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /*TK_QR_H*/
|
@ -0,0 +1,891 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "qrencode.h"
|
||||
#include "qrspec.h"
|
||||
#include "mqrspec.h"
|
||||
#include "bitstream.h"
|
||||
#include "qrinput.h"
|
||||
#include "rsecc.h"
|
||||
#include "split.h"
|
||||
#include "mask.h"
|
||||
#include "mmask.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Raw code
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
int dataLength;
|
||||
int eccLength;
|
||||
unsigned char *data;
|
||||
unsigned char *ecc;
|
||||
} RSblock;
|
||||
|
||||
typedef struct {
|
||||
int version;
|
||||
int dataLength;
|
||||
int eccLength;
|
||||
unsigned char *datacode;
|
||||
unsigned char *ecccode;
|
||||
int b1;
|
||||
int blocks;
|
||||
RSblock *rsblock;
|
||||
int count;
|
||||
} QRRawCode;
|
||||
|
||||
static void RSblock_initBlock(RSblock *block, int dl, unsigned char *data, int el, unsigned char *ecc)
|
||||
{
|
||||
block->dataLength = dl;
|
||||
block->data = data;
|
||||
block->eccLength = el;
|
||||
block->ecc = ecc;
|
||||
|
||||
RSECC_encode((size_t)dl, (size_t)el, data, ecc);
|
||||
}
|
||||
|
||||
static int RSblock_init(RSblock *blocks, int spec[5], unsigned char *data, unsigned char *ecc)
|
||||
{
|
||||
int i;
|
||||
RSblock *block;
|
||||
unsigned char *dp, *ep;
|
||||
int el, dl;
|
||||
|
||||
dl = QRspec_rsDataCodes1(spec);
|
||||
el = QRspec_rsEccCodes1(spec);
|
||||
|
||||
block = blocks;
|
||||
dp = data;
|
||||
ep = ecc;
|
||||
for(i = 0; i < QRspec_rsBlockNum1(spec); i++) {
|
||||
RSblock_initBlock(block, dl, dp, el, ep);
|
||||
dp += dl;
|
||||
ep += el;
|
||||
block++;
|
||||
}
|
||||
|
||||
if(QRspec_rsBlockNum2(spec) == 0) return 0;
|
||||
|
||||
dl = QRspec_rsDataCodes2(spec);
|
||||
el = QRspec_rsEccCodes2(spec);
|
||||
for(i = 0; i < QRspec_rsBlockNum2(spec); i++) {
|
||||
RSblock_initBlock(block, dl, dp, el, ep);
|
||||
dp += dl;
|
||||
ep += el;
|
||||
block++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE void QRraw_free(QRRawCode *raw);
|
||||
STATIC_IN_RELEASE QRRawCode *QRraw_new(QRinput *input)
|
||||
{
|
||||
QRRawCode *raw;
|
||||
int spec[5], ret;
|
||||
|
||||
raw = (QRRawCode *)TKMEM_ALLOC(sizeof(QRRawCode));
|
||||
if(raw == NULL) return NULL;
|
||||
|
||||
raw->datacode = QRinput_getByteStream(input);
|
||||
if(raw->datacode == NULL) {
|
||||
tk_free(raw);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QRspec_getEccSpec(input->version, input->level, spec);
|
||||
|
||||
raw->version = input->version;
|
||||
raw->b1 = QRspec_rsBlockNum1(spec);
|
||||
raw->dataLength = QRspec_rsDataLength(spec);
|
||||
raw->eccLength = QRspec_rsEccLength(spec);
|
||||
raw->ecccode = (unsigned char *)TKMEM_ALLOC((size_t)raw->eccLength);
|
||||
if(raw->ecccode == NULL) {
|
||||
tk_free(raw->datacode);
|
||||
tk_free(raw);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
raw->blocks = QRspec_rsBlockNum(spec);
|
||||
raw->rsblock = (RSblock *)TKMEM_CALLOC((size_t)(raw->blocks), sizeof(RSblock));
|
||||
if(raw->rsblock == NULL) {
|
||||
QRraw_free(raw);
|
||||
return NULL;
|
||||
}
|
||||
ret = RSblock_init(raw->rsblock, spec, raw->datacode, raw->ecccode);
|
||||
if(ret < 0) {
|
||||
QRraw_free(raw);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
raw->count = 0;
|
||||
|
||||
return raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a code (byte).
|
||||
* This function can be called iteratively.
|
||||
* @param raw raw code.
|
||||
* @return code
|
||||
*/
|
||||
STATIC_IN_RELEASE unsigned char QRraw_getCode(QRRawCode *raw)
|
||||
{
|
||||
int col, row;
|
||||
unsigned char ret;
|
||||
|
||||
if(raw->count < raw->dataLength) {
|
||||
row = raw->count % raw->blocks;
|
||||
col = raw->count / raw->blocks;
|
||||
if(col >= raw->rsblock[0].dataLength) {
|
||||
row += raw->b1;
|
||||
}
|
||||
ret = raw->rsblock[row].data[col];
|
||||
} else if(raw->count < raw->dataLength + raw->eccLength) {
|
||||
row = (raw->count - raw->dataLength) % raw->blocks;
|
||||
col = (raw->count - raw->dataLength) / raw->blocks;
|
||||
ret = raw->rsblock[row].ecc[col];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
raw->count++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE void QRraw_free(QRRawCode *raw)
|
||||
{
|
||||
if(raw != NULL) {
|
||||
tk_free(raw->datacode);
|
||||
tk_free(raw->ecccode);
|
||||
tk_free(raw->rsblock);
|
||||
tk_free(raw);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Raw code for Micro QR Code
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
int version;
|
||||
int dataLength;
|
||||
int eccLength;
|
||||
unsigned char *datacode;
|
||||
unsigned char *ecccode;
|
||||
RSblock *rsblock;
|
||||
int oddbits;
|
||||
int count;
|
||||
} MQRRawCode;
|
||||
|
||||
STATIC_IN_RELEASE void MQRraw_free(MQRRawCode *raw);
|
||||
STATIC_IN_RELEASE MQRRawCode *MQRraw_new(QRinput *input)
|
||||
{
|
||||
MQRRawCode *raw;
|
||||
|
||||
raw = (MQRRawCode *)TKMEM_ALLOC(sizeof(MQRRawCode));
|
||||
if(raw == NULL) return NULL;
|
||||
|
||||
raw->version = input->version;
|
||||
raw->dataLength = MQRspec_getDataLength(input->version, input->level);
|
||||
raw->eccLength = MQRspec_getECCLength(input->version, input->level);
|
||||
raw->oddbits = raw->dataLength * 8 - MQRspec_getDataLengthBit(input->version, input->level);
|
||||
raw->datacode = QRinput_getByteStream(input);
|
||||
if(raw->datacode == NULL) {
|
||||
tk_free(raw);
|
||||
return NULL;
|
||||
}
|
||||
raw->ecccode = (unsigned char *)TKMEM_ALLOC((size_t)raw->eccLength);
|
||||
if(raw->ecccode == NULL) {
|
||||
tk_free(raw->datacode);
|
||||
tk_free(raw);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
raw->rsblock = (RSblock *)TKMEM_CALLOC(1, sizeof(RSblock));
|
||||
if(raw->rsblock == NULL) {
|
||||
MQRraw_free(raw);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RSblock_initBlock(raw->rsblock, raw->dataLength, raw->datacode, raw->eccLength, raw->ecccode);
|
||||
|
||||
raw->count = 0;
|
||||
|
||||
return raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a code (byte).
|
||||
* This function can be called iteratively.
|
||||
* @param raw raw code.
|
||||
* @return code
|
||||
*/
|
||||
STATIC_IN_RELEASE unsigned char MQRraw_getCode(MQRRawCode *raw)
|
||||
{
|
||||
unsigned char ret;
|
||||
|
||||
if(raw->count < raw->dataLength) {
|
||||
ret = raw->datacode[raw->count];
|
||||
} else if(raw->count < raw->dataLength + raw->eccLength) {
|
||||
ret = raw->ecccode[raw->count - raw->dataLength];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
raw->count++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE void MQRraw_free(MQRRawCode *raw)
|
||||
{
|
||||
if(raw != NULL) {
|
||||
tk_free(raw->datacode);
|
||||
tk_free(raw->ecccode);
|
||||
tk_free(raw->rsblock);
|
||||
tk_free(raw);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Frame filling
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
int width;
|
||||
unsigned char *frame;
|
||||
int x, y;
|
||||
int dir;
|
||||
int bit;
|
||||
int mqr;
|
||||
} FrameFiller;
|
||||
|
||||
static void FrameFiller_set(FrameFiller *filler, int width, unsigned char *frame, int mqr)
|
||||
{
|
||||
filler->width = width;
|
||||
filler->frame = frame;
|
||||
filler->x = width - 1;
|
||||
filler->y = width - 1;
|
||||
filler->dir = -1;
|
||||
filler->bit = -1;
|
||||
filler->mqr = mqr;
|
||||
}
|
||||
|
||||
static unsigned char *FrameFiller_next(FrameFiller *filler)
|
||||
{
|
||||
unsigned char *p;
|
||||
int x, y, w;
|
||||
|
||||
if(filler->bit == -1) {
|
||||
filler->bit = 0;
|
||||
return filler->frame + filler->y * filler->width + filler->x;
|
||||
}
|
||||
|
||||
x = filler->x;
|
||||
y = filler->y;
|
||||
p = filler->frame;
|
||||
w = filler->width;
|
||||
|
||||
if(filler->bit == 0) {
|
||||
x--;
|
||||
filler->bit++;
|
||||
} else {
|
||||
x++;
|
||||
y += filler->dir;
|
||||
filler->bit--;
|
||||
}
|
||||
|
||||
if(filler->dir < 0) {
|
||||
if(y < 0) {
|
||||
y = 0;
|
||||
x -= 2;
|
||||
filler->dir = 1;
|
||||
if(!filler->mqr && x == 6) {
|
||||
x--;
|
||||
y = 9;
|
||||
}
|
||||
}
|
||||
} else if(y == w) {
|
||||
y = w - 1;
|
||||
x -= 2;
|
||||
filler->dir = -1;
|
||||
if(!filler->mqr && x == 6) {
|
||||
x--;
|
||||
y -= 8;
|
||||
}
|
||||
}
|
||||
if(x < 0 || y < 0) return NULL;
|
||||
|
||||
filler->x = x;
|
||||
filler->y = y;
|
||||
|
||||
if(p[y * w + x] & 0x80) {
|
||||
// This tail recursion could be optimized.
|
||||
return FrameFiller_next(filler);
|
||||
}
|
||||
return &p[y * w + x];
|
||||
}
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
unsigned char *FrameFiller_test(int version)
|
||||
{
|
||||
int width;
|
||||
unsigned char *frame, *p;
|
||||
int i, length;
|
||||
FrameFiller filler;
|
||||
|
||||
width = QRspec_getWidth(version);
|
||||
frame = QRspec_newFrame(version);
|
||||
if(frame == NULL) return NULL;
|
||||
FrameFiller_set(&filler, width, frame, 0);
|
||||
length = QRspec_getDataLength(version, QR_ECLEVEL_L) * 8
|
||||
+ QRspec_getECCLength(version, QR_ECLEVEL_L) * 8
|
||||
+ QRspec_getRemainder(version);
|
||||
for(i = 0; i < length; i++) {
|
||||
p = FrameFiller_next(&filler);
|
||||
if(p == NULL) {
|
||||
tk_free(frame);
|
||||
return NULL;
|
||||
}
|
||||
*p = (unsigned char)(i & 0x7f) | 0x80;
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
unsigned char *FrameFiller_testMQR(int version)
|
||||
{
|
||||
int width;
|
||||
unsigned char *frame, *p;
|
||||
int i, length;
|
||||
FrameFiller filler;
|
||||
|
||||
width = MQRspec_getWidth(version);
|
||||
frame = MQRspec_newFrame(version);
|
||||
if(frame == NULL) return NULL;
|
||||
FrameFiller_set(&filler, width, frame, 1);
|
||||
length = MQRspec_getDataLengthBit(version, QR_ECLEVEL_L)
|
||||
+ MQRspec_getECCLength(version, QR_ECLEVEL_L) * 8;
|
||||
for(i = 0; i < length; i++) {
|
||||
p = FrameFiller_next(&filler);
|
||||
if(p == NULL) {
|
||||
fprintf(stderr, "Frame filler run over the frame!\n");
|
||||
return frame;
|
||||
}
|
||||
*p = (unsigned char)(i & 0x7f) | 0x80;
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* QR-code encoding
|
||||
*****************************************************************************/
|
||||
|
||||
STATIC_IN_RELEASE QRcode *QRcode_new(int version, int width, unsigned char *data)
|
||||
{
|
||||
QRcode *qrcode;
|
||||
|
||||
qrcode = (QRcode *)TKMEM_ALLOC(sizeof(QRcode));
|
||||
if(qrcode == NULL) return NULL;
|
||||
|
||||
qrcode->version = version;
|
||||
qrcode->width = width;
|
||||
qrcode->data = data;
|
||||
|
||||
return qrcode;
|
||||
}
|
||||
|
||||
void QRcode_free(QRcode *qrcode)
|
||||
{
|
||||
if(qrcode != NULL) {
|
||||
tk_free(qrcode->data);
|
||||
tk_free(qrcode);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE QRcode *QRcode_encodeMask(QRinput *input, int mask)
|
||||
{
|
||||
int width, version;
|
||||
QRRawCode *raw;
|
||||
unsigned char *frame, *masked, *p, code, bit;
|
||||
int i, j;
|
||||
QRcode *qrcode = NULL;
|
||||
FrameFiller filler;
|
||||
|
||||
if(input->mqr) {
|
||||
return NULL;
|
||||
}
|
||||
if(input->version < 0 || input->version > QRSPEC_VERSION_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
if(input->level > QR_ECLEVEL_H) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
raw = QRraw_new(input);
|
||||
if(raw == NULL) return NULL;
|
||||
|
||||
version = raw->version;
|
||||
width = QRspec_getWidth(version);
|
||||
frame = QRspec_newFrame(version);
|
||||
if(frame == NULL) {
|
||||
QRraw_free(raw);
|
||||
return NULL;
|
||||
}
|
||||
FrameFiller_set(&filler, width, frame, 0);
|
||||
|
||||
/* interleaved data and ecc codes */
|
||||
for(i = 0; i < raw->dataLength; i++) {
|
||||
code = QRraw_getCode(raw);
|
||||
bit = 0x80;
|
||||
for(j = 0; j < 8; j++) {
|
||||
p = FrameFiller_next(&filler);
|
||||
if(p == NULL) goto EXIT;
|
||||
*p = ((bit & code) != 0);
|
||||
bit = bit >> 1;
|
||||
}
|
||||
}
|
||||
for(i = 0; i < raw->eccLength; i++) {
|
||||
code = QRraw_getCode(raw);
|
||||
bit = 0x80;
|
||||
for(j = 0; j < 8; j++) {
|
||||
p = FrameFiller_next(&filler);
|
||||
if(p == NULL) goto EXIT;
|
||||
*p = 0x02 | ((bit & code) != 0);
|
||||
bit = bit >> 1;
|
||||
}
|
||||
}
|
||||
QRraw_free(raw);
|
||||
raw = NULL;
|
||||
/* remainder bits */
|
||||
j = QRspec_getRemainder(version);
|
||||
for(i = 0; i < j; i++) {
|
||||
p = FrameFiller_next(&filler);
|
||||
if(p == NULL) goto EXIT;
|
||||
*p = 0x02;
|
||||
}
|
||||
|
||||
/* masking */
|
||||
if(mask == -2) { // just for debug purpose
|
||||
masked = (unsigned char *)TKMEM_ALLOC((size_t)(width * width));
|
||||
memcpy(masked, frame, (size_t)(width * width));
|
||||
} else if(mask < 0) {
|
||||
masked = Mask_mask(width, frame, input->level);
|
||||
} else {
|
||||
masked = Mask_makeMask(width, frame, mask, input->level);
|
||||
}
|
||||
if(masked == NULL) {
|
||||
goto EXIT;
|
||||
}
|
||||
qrcode = QRcode_new(version, width, masked);
|
||||
if(qrcode == NULL) {
|
||||
tk_free(masked);
|
||||
}
|
||||
|
||||
EXIT:
|
||||
QRraw_free(raw);
|
||||
tk_free(frame);
|
||||
return qrcode;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE QRcode *QRcode_encodeMaskMQR(QRinput *input, int mask)
|
||||
{
|
||||
int width, version;
|
||||
MQRRawCode *raw;
|
||||
unsigned char *frame, *masked, *p, code, bit;
|
||||
int i, j, length;
|
||||
QRcode *qrcode = NULL;
|
||||
FrameFiller filler;
|
||||
|
||||
if(!input->mqr) {
|
||||
return NULL;
|
||||
}
|
||||
if(input->version <= 0 || input->version > MQRSPEC_VERSION_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
if(input->level > QR_ECLEVEL_Q) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
raw = MQRraw_new(input);
|
||||
if(raw == NULL) return NULL;
|
||||
|
||||
version = raw->version;
|
||||
width = MQRspec_getWidth(version);
|
||||
frame = MQRspec_newFrame(version);
|
||||
if(frame == NULL) {
|
||||
MQRraw_free(raw);
|
||||
return NULL;
|
||||
}
|
||||
FrameFiller_set(&filler, width, frame, 1);
|
||||
|
||||
/* interleaved data and ecc codes */
|
||||
for(i = 0; i < raw->dataLength; i++) {
|
||||
code = MQRraw_getCode(raw);
|
||||
bit = 0x80;
|
||||
if(raw->oddbits && i == raw->dataLength - 1) {
|
||||
length = raw->oddbits;
|
||||
} else {
|
||||
length = 8;
|
||||
}
|
||||
for(j = 0; j < length; j++) {
|
||||
p = FrameFiller_next(&filler);
|
||||
if(p == NULL) goto EXIT;
|
||||
*p = ((bit & code) != 0);
|
||||
bit = bit >> 1;
|
||||
}
|
||||
}
|
||||
for(i = 0; i < raw->eccLength; i++) {
|
||||
code = MQRraw_getCode(raw);
|
||||
bit = 0x80;
|
||||
length = 8;
|
||||
for(j = 0; j < length; j++) {
|
||||
p = FrameFiller_next(&filler);
|
||||
if(p == NULL) goto EXIT;
|
||||
*p = 0x02 | ((bit & code) != 0);
|
||||
bit = bit >> 1;
|
||||
}
|
||||
}
|
||||
MQRraw_free(raw);
|
||||
raw = NULL;
|
||||
|
||||
/* masking */
|
||||
if(mask == -2) { // just for debug purpose
|
||||
masked = (unsigned char *)TKMEM_ALLOC((size_t)(width * width));
|
||||
memcpy(masked, frame, (size_t)(width * width));
|
||||
} else if(mask < 0) {
|
||||
masked = MMask_mask(version, frame, input->level);
|
||||
} else {
|
||||
masked = MMask_makeMask(version, frame, mask, input->level);
|
||||
}
|
||||
if(masked == NULL) {
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
qrcode = QRcode_new(version, width, masked);
|
||||
if(qrcode == NULL) {
|
||||
tk_free(masked);
|
||||
}
|
||||
|
||||
EXIT:
|
||||
MQRraw_free(raw);
|
||||
tk_free(frame);
|
||||
return qrcode;
|
||||
}
|
||||
|
||||
QRcode *QRcode_encodeInput(QRinput *input)
|
||||
{
|
||||
if(input->mqr) {
|
||||
return QRcode_encodeMaskMQR(input, -1);
|
||||
} else {
|
||||
return QRcode_encodeMask(input, -1);
|
||||
}
|
||||
}
|
||||
|
||||
static QRcode *QRcode_encodeStringReal(const char *string, int version, QRecLevel level, int mqr, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
QRinput *input;
|
||||
QRcode *code;
|
||||
int ret;
|
||||
|
||||
if(string == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if(hint != QR_MODE_8 && hint != QR_MODE_KANJI) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(mqr) {
|
||||
input = QRinput_newMQR(version, level);
|
||||
} else {
|
||||
input = QRinput_new2(version, level);
|
||||
}
|
||||
if(input == NULL) return NULL;
|
||||
|
||||
ret = Split_splitStringToQRinput(string, input, hint, casesensitive);
|
||||
if(ret < 0) {
|
||||
QRinput_free(input);
|
||||
return NULL;
|
||||
}
|
||||
code = QRcode_encodeInput(input);
|
||||
QRinput_free(input);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
return QRcode_encodeStringReal(string, version, level, 0, hint, casesensitive);
|
||||
}
|
||||
|
||||
QRcode *QRcode_encodeStringMQR(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
return QRcode_encodeStringReal(string, version, level, 1, hint, casesensitive);
|
||||
}
|
||||
|
||||
static QRcode *QRcode_encodeDataReal(const unsigned char *data, int length, int version, QRecLevel level, int mqr)
|
||||
{
|
||||
QRinput *input;
|
||||
QRcode *code;
|
||||
int ret;
|
||||
|
||||
if(data == NULL || length == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(mqr) {
|
||||
input = QRinput_newMQR(version, level);
|
||||
} else {
|
||||
input = QRinput_new2(version, level);
|
||||
}
|
||||
if(input == NULL) return NULL;
|
||||
|
||||
ret = QRinput_append(input, QR_MODE_8, length, data);
|
||||
if(ret < 0) {
|
||||
QRinput_free(input);
|
||||
return NULL;
|
||||
}
|
||||
code = QRcode_encodeInput(input);
|
||||
QRinput_free(input);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
QRcode *QRcode_encodeData(int size, const unsigned char *data, int version, QRecLevel level)
|
||||
{
|
||||
return QRcode_encodeDataReal(data, size, version, level, 0);
|
||||
}
|
||||
|
||||
QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level)
|
||||
{
|
||||
if(string == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return QRcode_encodeDataReal((unsigned char *)string, (int)strlen(string), version, level, 0);
|
||||
}
|
||||
|
||||
QRcode *QRcode_encodeDataMQR(int size, const unsigned char *data, int version, QRecLevel level)
|
||||
{
|
||||
return QRcode_encodeDataReal(data, size, version, level, 1);
|
||||
}
|
||||
|
||||
QRcode *QRcode_encodeString8bitMQR(const char *string, int version, QRecLevel level)
|
||||
{
|
||||
if(string == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return QRcode_encodeDataReal((unsigned char *)string, (int)strlen(string), version, level, 1);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Structured QR-code encoding
|
||||
*****************************************************************************/
|
||||
|
||||
static QRcode_List *QRcode_List_newEntry(void)
|
||||
{
|
||||
QRcode_List *entry;
|
||||
|
||||
entry = (QRcode_List *)TKMEM_ALLOC(sizeof(QRcode_List));
|
||||
if(entry == NULL) return NULL;
|
||||
|
||||
entry->next = NULL;
|
||||
entry->code = NULL;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
static void QRcode_List_freeEntry(QRcode_List *entry)
|
||||
{
|
||||
if(entry != NULL) {
|
||||
QRcode_free(entry->code);
|
||||
tk_free(entry);
|
||||
}
|
||||
}
|
||||
|
||||
void QRcode_List_free(QRcode_List *qrlist)
|
||||
{
|
||||
QRcode_List *list = qrlist, *next;
|
||||
|
||||
while(list != NULL) {
|
||||
next = list->next;
|
||||
QRcode_List_freeEntry(list);
|
||||
list = next;
|
||||
}
|
||||
}
|
||||
|
||||
int QRcode_List_size(QRcode_List *qrlist)
|
||||
{
|
||||
QRcode_List *list = qrlist;
|
||||
int size = 0;
|
||||
|
||||
while(list != NULL) {
|
||||
size++;
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static unsigned char QRcode_parity(const char *str, int size)
|
||||
{
|
||||
unsigned char parity = 0;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < size; i++) {
|
||||
parity ^= str[i];
|
||||
}
|
||||
|
||||
return parity;
|
||||
}
|
||||
#endif
|
||||
|
||||
QRcode_List *QRcode_encodeInputStructured(QRinput_Struct *s)
|
||||
{
|
||||
QRcode_List *head = NULL;
|
||||
QRcode_List *tail = NULL;
|
||||
QRcode_List *entry;
|
||||
QRinput_InputList *list = s->head;
|
||||
|
||||
while(list != NULL) {
|
||||
if(head == NULL) {
|
||||
entry = QRcode_List_newEntry();
|
||||
if(entry == NULL) goto ABORT;
|
||||
head = entry;
|
||||
tail = head;
|
||||
} else {
|
||||
entry = QRcode_List_newEntry();
|
||||
if(entry == NULL) goto ABORT;
|
||||
tail->next = entry;
|
||||
tail = tail->next;
|
||||
}
|
||||
tail->code = QRcode_encodeInput(list->input);
|
||||
if(tail->code == NULL) {
|
||||
goto ABORT;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return head;
|
||||
ABORT:
|
||||
QRcode_List_free(head);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static QRcode_List *QRcode_encodeInputToStructured(QRinput *input)
|
||||
{
|
||||
QRinput_Struct *s;
|
||||
QRcode_List *codes;
|
||||
|
||||
s = QRinput_splitQRinputToStruct(input);
|
||||
if(s == NULL) return NULL;
|
||||
|
||||
codes = QRcode_encodeInputStructured(s);
|
||||
QRinput_Struct_free(s);
|
||||
|
||||
return codes;
|
||||
}
|
||||
|
||||
static QRcode_List *QRcode_encodeDataStructuredReal(
|
||||
int size, const unsigned char *data,
|
||||
int version, QRecLevel level,
|
||||
int eightbit, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
QRinput *input;
|
||||
QRcode_List *codes;
|
||||
int ret;
|
||||
|
||||
if(version <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
if(!eightbit && (hint != QR_MODE_8 && hint != QR_MODE_KANJI)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
input = QRinput_new2(version, level);
|
||||
if(input == NULL) return NULL;
|
||||
|
||||
if(eightbit) {
|
||||
ret = QRinput_append(input, QR_MODE_8, size, data);
|
||||
} else {
|
||||
ret = Split_splitStringToQRinput((char *)data, input, hint, casesensitive);
|
||||
}
|
||||
if(ret < 0) {
|
||||
QRinput_free(input);
|
||||
return NULL;
|
||||
}
|
||||
codes = QRcode_encodeInputToStructured(input);
|
||||
QRinput_free(input);
|
||||
|
||||
return codes;
|
||||
}
|
||||
|
||||
QRcode_List *QRcode_encodeDataStructured(int size, const unsigned char *data, int version, QRecLevel level) {
|
||||
return QRcode_encodeDataStructuredReal(size, data, version, level, 1, QR_MODE_NUL, 0);
|
||||
}
|
||||
|
||||
QRcode_List *QRcode_encodeString8bitStructured(const char *string, int version, QRecLevel level) {
|
||||
if(string == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return QRcode_encodeDataStructured((int)strlen(string), (unsigned char *)string, version, level);
|
||||
}
|
||||
|
||||
QRcode_List *QRcode_encodeStringStructured(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
if(string == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return QRcode_encodeDataStructuredReal((int)strlen(string), (unsigned char *)string, version, level, 0, hint, casesensitive);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* System utilities
|
||||
*****************************************************************************/
|
||||
|
||||
void QRcode_APIVersion(int *major_version, int *minor_version, int *micro_version)
|
||||
{
|
||||
if(major_version != NULL) {
|
||||
*major_version = MAJOR_VERSION;
|
||||
}
|
||||
if(minor_version != NULL) {
|
||||
*minor_version = MINOR_VERSION;
|
||||
}
|
||||
if(micro_version != NULL) {
|
||||
*micro_version = MICRO_VERSION;
|
||||
}
|
||||
}
|
||||
|
||||
char *QRcode_APIVersionString(void)
|
||||
{
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
void QRcode_clearCache(void)
|
||||
{
|
||||
return;
|
||||
}
|
@ -0,0 +1,568 @@
|
||||
/**
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** \mainpage
|
||||
* Libqrencode is a library for encoding data in a QR Code symbol, a kind of 2D
|
||||
* symbology.
|
||||
*
|
||||
* \section encoding Encoding
|
||||
*
|
||||
* There are two methods to encode data: <b>encoding a string/data</b> or
|
||||
* <b>encoding a structured data</b>.
|
||||
*
|
||||
* \subsection encoding-string Encoding a string/data
|
||||
* You can encode a string by calling QRcode_encodeString().
|
||||
* The given string is parsed automatically and encoded. If you want to encode
|
||||
* data that can be represented as a C string style (NUL terminated), you can
|
||||
* simply use this way.
|
||||
*
|
||||
* If the input data contains Kanji (Shift-JIS) characters and you want to
|
||||
* encode them as Kanji in QR Code, you should give QR_MODE_KANJI as a hint.
|
||||
* Otherwise, all of non-alphanumeric characters are encoded as 8 bit data.
|
||||
* If you want to encode a whole string in 8 bit mode, you can use
|
||||
* QRcode_encodeString8bit() instead.
|
||||
*
|
||||
* Please note that a C string can not contain NUL characters. If your data
|
||||
* contains NUL, you must use QRcode_encodeData().
|
||||
*
|
||||
* \subsection encoding-input Encoding a structured data
|
||||
* You can construct a structured input data manually. If the structure of the
|
||||
* input data is known, you can use this way.
|
||||
* At first, create a ::QRinput object by QRinput_new(). Then add input data
|
||||
* to the QRinput object by QRinput_append(). Finally call QRcode_encodeInput()
|
||||
* to encode the QRinput data.
|
||||
* You can reuse the QRinput data again to encode it in other symbols with
|
||||
* different parameters.
|
||||
*
|
||||
* \section result Result
|
||||
* The encoded symbol is resulted as a ::QRcode object. It will contain
|
||||
* its version number, width of the symbol and an array represents the symbol.
|
||||
* See ::QRcode for the details. You can free the object by QRcode_free().
|
||||
*
|
||||
* Please note that the version of the result may be larger than specified.
|
||||
* In such cases, the input data would be too large to be encoded in a
|
||||
* symbol of the specified version.
|
||||
*
|
||||
* \section structured Structured append
|
||||
* Libqrencode can generate "Structured-appended" symbols that enables to split
|
||||
* a large data set into mulitple QR codes. A QR code reader concatenates
|
||||
* multiple QR code symbols into a string.
|
||||
* Just like QRcode_encodeString(), you can use QRcode_encodeStringStructured()
|
||||
* to generate structured-appended symbols. This functions returns an instance
|
||||
* of ::QRcode_List. The returned list is a singly-linked list of QRcode: you
|
||||
* can retrieve each QR code in this way:
|
||||
*
|
||||
* \code
|
||||
* QRcode_List *qrcodes;
|
||||
* QRcode_List *entry;
|
||||
* QRcode *qrcode;
|
||||
*
|
||||
* qrcodes = QRcode_encodeStringStructured(...);
|
||||
* entry = qrcodes;
|
||||
* while(entry != NULL) {
|
||||
* qrcode = entry->code;
|
||||
* // do something
|
||||
* entry = entry->next;
|
||||
* }
|
||||
* QRcode_List_free(entry);
|
||||
* \endcode
|
||||
*
|
||||
* Instead of using auto-parsing functions, you can construct your own
|
||||
* structured input. At first, instantiate an object of ::QRinput_Struct
|
||||
* by calling QRinput_Struct_new(). This object can hold multiple ::QRinput,
|
||||
* and one QR code is generated for a ::QRinput.
|
||||
* QRinput_Struct_appendInput() appends a ::QRinput to a ::QRinput_Struct
|
||||
* object. In order to generate structured-appended symbols, it is required to
|
||||
* embed headers to each symbol. You can use
|
||||
* QRinput_Struct_insertStructuredAppendHeaders() to insert appropriate
|
||||
* headers to each symbol. You should call this function just once before
|
||||
* encoding symbols.
|
||||
*/
|
||||
|
||||
#ifndef QRENCODE_H
|
||||
#define QRENCODE_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Encoding mode.
|
||||
*/
|
||||
typedef enum {
|
||||
QR_MODE_NUL = -1, ///< Terminator (NUL character). Internal use only
|
||||
QR_MODE_NUM = 0, ///< Numeric mode
|
||||
QR_MODE_AN, ///< Alphabet-numeric mode
|
||||
QR_MODE_8, ///< 8-bit data mode
|
||||
QR_MODE_KANJI, ///< Kanji (shift-jis) mode
|
||||
QR_MODE_STRUCTURE, ///< Internal use only
|
||||
QR_MODE_ECI, ///< ECI mode
|
||||
QR_MODE_FNC1FIRST, ///< FNC1, first position
|
||||
QR_MODE_FNC1SECOND, ///< FNC1, second position
|
||||
} QRencodeMode;
|
||||
|
||||
/**
|
||||
* Level of error correction.
|
||||
*/
|
||||
typedef enum {
|
||||
QR_ECLEVEL_L = 0, ///< lowest
|
||||
QR_ECLEVEL_M,
|
||||
QR_ECLEVEL_Q,
|
||||
QR_ECLEVEL_H ///< highest
|
||||
} QRecLevel;
|
||||
|
||||
/**
|
||||
* Maximum version (size) of QR-code symbol.
|
||||
*/
|
||||
#define QRSPEC_VERSION_MAX 40
|
||||
|
||||
/**
|
||||
* Maximum version (size) of QR-code symbol.
|
||||
*/
|
||||
#define MQRSPEC_VERSION_MAX 4
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Input data (qrinput.c)
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Singly linked list to contain input strings. An instance of this class
|
||||
* contains its version and error correction level too. It is required to
|
||||
* set them by QRinput_setVersion() and QRinput_setErrorCorrectionLevel(),
|
||||
* or use QRinput_new2() to instantiate an object.
|
||||
*/
|
||||
typedef struct _QRinput QRinput;
|
||||
|
||||
/**
|
||||
* Instantiate an input data object. The version is set to 0 (auto-select)
|
||||
* and the error correction level is set to QR_ECLEVEL_L.
|
||||
* @return an input object (initialized). On error, NULL is returned and errno
|
||||
* is set to indicate the error.
|
||||
* @throw ENOMEM unable to allocate memory.
|
||||
*/
|
||||
extern QRinput *QRinput_new(void);
|
||||
|
||||
/**
|
||||
* Instantiate an input data object.
|
||||
* @param version version number.
|
||||
* @param level Error correction level.
|
||||
* @return an input object (initialized). On error, NULL is returned and errno
|
||||
* is set to indicate the error.
|
||||
* @throw ENOMEM unable to allocate memory for input objects.
|
||||
* @throw EINVAL invalid arguments.
|
||||
*/
|
||||
extern QRinput *QRinput_new2(int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Instantiate an input data object. Object's Micro QR Code flag is set.
|
||||
* Unlike with full-sized QR Code, version number must be specified (>0).
|
||||
* @param version version number (1--4).
|
||||
* @param level Error correction level.
|
||||
* @return an input object (initialized). On error, NULL is returned and errno
|
||||
* is set to indicate the error.
|
||||
* @throw ENOMEM unable to allocate memory for input objects.
|
||||
* @throw EINVAL invalid arguments.
|
||||
*/
|
||||
extern QRinput *QRinput_newMQR(int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Append data to an input object.
|
||||
* The data is copied and appended to the input object.
|
||||
* @param input input object.
|
||||
* @param mode encoding mode.
|
||||
* @param size size of data (byte).
|
||||
* @param data a pointer to the memory area of the input data.
|
||||
* @retval 0 success.
|
||||
* @retval -1 an error occurred and errno is set to indeicate the error.
|
||||
* See Execptions for the details.
|
||||
* @throw ENOMEM unable to allocate memory.
|
||||
* @throw EINVAL input data is invalid.
|
||||
*
|
||||
*/
|
||||
extern int QRinput_append(QRinput *input, QRencodeMode mode, int size, const unsigned char *data);
|
||||
|
||||
/**
|
||||
* Append ECI header.
|
||||
* @param input input object.
|
||||
* @param ecinum ECI indicator number (0 - 999999)
|
||||
* @retval 0 success.
|
||||
* @retval -1 an error occurred and errno is set to indeicate the error.
|
||||
* See Execptions for the details.
|
||||
* @throw ENOMEM unable to allocate memory.
|
||||
* @throw EINVAL input data is invalid.
|
||||
*
|
||||
*/
|
||||
extern int QRinput_appendECIheader(QRinput *input, unsigned int ecinum);
|
||||
|
||||
/**
|
||||
* Get current version.
|
||||
* @param input input object.
|
||||
* @return current version.
|
||||
*/
|
||||
extern int QRinput_getVersion(QRinput *input);
|
||||
|
||||
/**
|
||||
* Set version of the QR code that is to be encoded.
|
||||
* This function cannot be applied to Micro QR Code.
|
||||
* @param input input object.
|
||||
* @param version version number (0 = auto)
|
||||
* @retval 0 success.
|
||||
* @retval -1 invalid argument.
|
||||
*/
|
||||
extern int QRinput_setVersion(QRinput *input, int version);
|
||||
|
||||
/**
|
||||
* Get current error correction level.
|
||||
* @param input input object.
|
||||
* @return Current error correcntion level.
|
||||
*/
|
||||
extern QRecLevel QRinput_getErrorCorrectionLevel(QRinput *input);
|
||||
|
||||
/**
|
||||
* Set error correction level of the QR code that is to be encoded.
|
||||
* This function cannot be applied to Micro QR Code.
|
||||
* @param input input object.
|
||||
* @param level Error correction level.
|
||||
* @retval 0 success.
|
||||
* @retval -1 invalid argument.
|
||||
*/
|
||||
extern int QRinput_setErrorCorrectionLevel(QRinput *input, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Set version and error correction level of the QR code at once.
|
||||
* This function is recommened for Micro QR Code.
|
||||
* @param input input object.
|
||||
* @param version version number (0 = auto)
|
||||
* @param level Error correction level.
|
||||
* @retval 0 success.
|
||||
* @retval -1 invalid argument.
|
||||
*/
|
||||
extern int QRinput_setVersionAndErrorCorrectionLevel(QRinput *input, int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Free the input object.
|
||||
* All of data chunks in the input object are freed too.
|
||||
* @param input input object.
|
||||
*/
|
||||
extern void QRinput_free(QRinput *input);
|
||||
|
||||
/**
|
||||
* Validate the input data.
|
||||
* @param mode encoding mode.
|
||||
* @param size size of data (byte).
|
||||
* @param data a pointer to the memory area of the input data.
|
||||
* @retval 0 success.
|
||||
* @retval -1 invalid arguments.
|
||||
*/
|
||||
extern int QRinput_check(QRencodeMode mode, int size, const unsigned char *data);
|
||||
|
||||
/**
|
||||
* Set of QRinput for structured symbols.
|
||||
*/
|
||||
typedef struct _QRinput_Struct QRinput_Struct;
|
||||
|
||||
/**
|
||||
* Instantiate a set of input data object.
|
||||
* @return an instance of QRinput_Struct. On error, NULL is returned and errno
|
||||
* is set to indicate the error.
|
||||
* @throw ENOMEM unable to allocate memory.
|
||||
*/
|
||||
extern QRinput_Struct *QRinput_Struct_new(void);
|
||||
|
||||
/**
|
||||
* Set parity of structured symbols.
|
||||
* @param s structured input object.
|
||||
* @param parity parity of s.
|
||||
*/
|
||||
extern void QRinput_Struct_setParity(QRinput_Struct *s, unsigned char parity);
|
||||
|
||||
/**
|
||||
* Append a QRinput object to the set. QRinput created by QRinput_newMQR()
|
||||
* will be rejected.
|
||||
* @warning never append the same QRinput object twice or more.
|
||||
* @param s structured input object.
|
||||
* @param input an input object.
|
||||
* @retval >0 number of input objects in the structure.
|
||||
* @retval -1 an error occurred. See Exceptions for the details.
|
||||
* @throw ENOMEM unable to allocate memory.
|
||||
* @throw EINVAL invalid arguments.
|
||||
*/
|
||||
extern int QRinput_Struct_appendInput(QRinput_Struct *s, QRinput *input);
|
||||
|
||||
/**
|
||||
* Free all of QRinput in the set.
|
||||
* @param s a structured input object.
|
||||
*/
|
||||
extern void QRinput_Struct_free(QRinput_Struct *s);
|
||||
|
||||
/**
|
||||
* Split a QRinput to QRinput_Struct. It calculates a parity, set it, then
|
||||
* insert structured-append headers. QRinput created by QRinput_newMQR() will
|
||||
* be rejected.
|
||||
* @param input input object. Version number and error correction level must be
|
||||
* set.
|
||||
* @return a set of input data. On error, NULL is returned, and errno is set
|
||||
* to indicate the error. See Exceptions for the details.
|
||||
* @throw ERANGE input data is too large.
|
||||
* @throw EINVAL invalid input data.
|
||||
* @throw ENOMEM unable to allocate memory.
|
||||
*/
|
||||
extern QRinput_Struct *QRinput_splitQRinputToStruct(QRinput *input);
|
||||
|
||||
/**
|
||||
* Insert structured-append headers to the input structure. It calculates
|
||||
* a parity and set it if the parity is not set yet.
|
||||
* @param s input structure
|
||||
* @retval 0 success.
|
||||
* @retval -1 an error occurred and errno is set to indeicate the error.
|
||||
* See Execptions for the details.
|
||||
* @throw EINVAL invalid input object.
|
||||
* @throw ENOMEM unable to allocate memory.
|
||||
*/
|
||||
extern int QRinput_Struct_insertStructuredAppendHeaders(QRinput_Struct *s);
|
||||
|
||||
/**
|
||||
* Set FNC1-1st position flag.
|
||||
*/
|
||||
extern int QRinput_setFNC1First(QRinput *input);
|
||||
|
||||
/**
|
||||
* Set FNC1-2nd position flag and application identifier.
|
||||
*/
|
||||
extern int QRinput_setFNC1Second(QRinput *input, unsigned char appid);
|
||||
|
||||
/******************************************************************************
|
||||
* QRcode output (qrencode.c)
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* QRcode class.
|
||||
* Symbol data is represented as an array contains width*width uchars.
|
||||
* Each uchar represents a module (dot). If the less significant bit of
|
||||
* the uchar is 1, the corresponding module is black. The other bits are
|
||||
* meaningless for usual applications, but here its specification is described.
|
||||
*
|
||||
* @verbatim
|
||||
MSB 76543210 LSB
|
||||
|||||||`- 1=black/0=white
|
||||
||||||`-- 1=ecc/0=data code area
|
||||
|||||`--- format information
|
||||
||||`---- version information
|
||||
|||`----- timing pattern
|
||||
||`------ alignment pattern
|
||||
|`------- finder pattern and separator
|
||||
`-------- non-data modules (format, timing, etc.)
|
||||
@endverbatim
|
||||
*/
|
||||
typedef struct {
|
||||
int version; ///< version of the symbol
|
||||
int width; ///< width of the symbol
|
||||
unsigned char *data; ///< symbol data
|
||||
} QRcode;
|
||||
|
||||
/**
|
||||
* Singly-linked list of QRcode. Used to represent a structured symbols.
|
||||
* A list is terminated with NULL.
|
||||
*/
|
||||
typedef struct _QRcode_List {
|
||||
QRcode *code;
|
||||
struct _QRcode_List *next;
|
||||
} QRcode_List;
|
||||
|
||||
/**
|
||||
* Create a symbol from the input data.
|
||||
* @warning This function is THREAD UNSAFE when pthread is disabled.
|
||||
* @param input input data.
|
||||
* @return an instance of QRcode class. The version of the result QRcode may
|
||||
* be larger than the designated version. On error, NULL is returned,
|
||||
* and errno is set to indicate the error. See Exceptions for the
|
||||
* details.
|
||||
* @throw EINVAL invalid input object.
|
||||
* @throw ENOMEM unable to allocate memory for input objects.
|
||||
*/
|
||||
extern QRcode *QRcode_encodeInput(QRinput *input);
|
||||
|
||||
/**
|
||||
* Create a symbol from the string. The library automatically parses the input
|
||||
* string and encodes in a QR Code symbol.
|
||||
* @warning This function is THREAD UNSAFE when pthread is disabled.
|
||||
* @param string input string. It must be NUL terminated.
|
||||
* @param version version of the symbol. If 0, the library chooses the minimum
|
||||
* version for the given input data.
|
||||
* @param level error correction level.
|
||||
* @param hint tell the library how Japanese Kanji characters should be
|
||||
* encoded. If QR_MODE_KANJI is given, the library assumes that the
|
||||
* given string contains Shift-JIS characters and encodes them in
|
||||
* Kanji-mode. If QR_MODE_8 is given, all of non-alphanumerical
|
||||
* characters will be encoded as is. If you want to embed UTF-8
|
||||
* string, choose this. Other mode will cause EINVAL error.
|
||||
* @param casesensitive case-sensitive(1) or not(0).
|
||||
* @return an instance of QRcode class. The version of the result QRcode may
|
||||
* be larger than the designated version. On error, NULL is returned,
|
||||
* and errno is set to indicate the error. See Exceptions for the
|
||||
* details.
|
||||
* @throw EINVAL invalid input object.
|
||||
* @throw ENOMEM unable to allocate memory for input objects.
|
||||
* @throw ERANGE input data is too large.
|
||||
*/
|
||||
extern QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
|
||||
|
||||
/**
|
||||
* Same to QRcode_encodeString(), but encode whole data in 8-bit mode.
|
||||
* @warning This function is THREAD UNSAFE when pthread is disabled.
|
||||
*/
|
||||
extern QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Micro QR Code version of QRcode_encodeString().
|
||||
* @warning This function is THREAD UNSAFE when pthread is disabled.
|
||||
*/
|
||||
extern QRcode *QRcode_encodeStringMQR(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
|
||||
|
||||
/**
|
||||
* Micro QR Code version of QRcode_encodeString8bit().
|
||||
* @warning This function is THREAD UNSAFE when pthread is disabled.
|
||||
*/
|
||||
extern QRcode *QRcode_encodeString8bitMQR(const char *string, int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Encode byte stream (may include '\0') in 8-bit mode.
|
||||
* @warning This function is THREAD UNSAFE when pthread is disabled.
|
||||
* @param size size of the input data.
|
||||
* @param data input data.
|
||||
* @param version version of the symbol. If 0, the library chooses the minimum
|
||||
* version for the given input data.
|
||||
* @param level error correction level.
|
||||
* @throw EINVAL invalid input object.
|
||||
* @throw ENOMEM unable to allocate memory for input objects.
|
||||
* @throw ERANGE input data is too large.
|
||||
*/
|
||||
extern QRcode *QRcode_encodeData(int size, const unsigned char *data, int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Micro QR Code version of QRcode_encodeData().
|
||||
* @warning This function is THREAD UNSAFE when pthread is disabled.
|
||||
*/
|
||||
extern QRcode *QRcode_encodeDataMQR(int size, const unsigned char *data, int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Free the instance of QRcode class.
|
||||
* @param qrcode an instance of QRcode class.
|
||||
*/
|
||||
extern void QRcode_free(QRcode *qrcode);
|
||||
|
||||
/**
|
||||
* Create structured symbols from the input data.
|
||||
* @warning This function is THREAD UNSAFE when pthread is disabled.
|
||||
* @param s input data, structured.
|
||||
* @return a singly-linked list of QRcode.
|
||||
*/
|
||||
extern QRcode_List *QRcode_encodeInputStructured(QRinput_Struct *s);
|
||||
|
||||
/**
|
||||
* Create structured symbols from the string. The library automatically parses
|
||||
* the input string and encodes in a QR Code symbol.
|
||||
* @warning This function is THREAD UNSAFE when pthread is disabled.
|
||||
* @param string input string. It must be NUL terminated.
|
||||
* @param version version of the symbol.
|
||||
* @param level error correction level.
|
||||
* @param hint tell the library how Japanese Kanji characters should be
|
||||
* encoded. If QR_MODE_KANJI is given, the library assumes that the
|
||||
* given string contains Shift-JIS characters and encodes them in
|
||||
* Kanji-mode. If QR_MODE_8 is given, all of non-alphanumerical
|
||||
* characters will be encoded as is. If you want to embed UTF-8
|
||||
* string, choose this. Other mode will cause EINVAL error.
|
||||
* @param casesensitive case-sensitive(1) or not(0).
|
||||
* @return a singly-linked list of QRcode. On error, NULL is returned, and
|
||||
* errno is set to indicate the error. See Exceptions for the details.
|
||||
* @throw EINVAL invalid input object.
|
||||
* @throw ENOMEM unable to allocate memory for input objects.
|
||||
*/
|
||||
extern QRcode_List *QRcode_encodeStringStructured(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
|
||||
|
||||
/**
|
||||
* Same to QRcode_encodeStringStructured(), but encode whole data in 8-bit mode.
|
||||
* @warning This function is THREAD UNSAFE when pthread is disabled.
|
||||
*/
|
||||
extern QRcode_List *QRcode_encodeString8bitStructured(const char *string, int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Create structured symbols from byte stream (may include '\0'). Wholde data
|
||||
* are encoded in 8-bit mode.
|
||||
* @warning This function is THREAD UNSAFE when pthread is disabled.
|
||||
* @param size size of the input data.
|
||||
* @param data input dat.
|
||||
* @param version version of the symbol.
|
||||
* @param level error correction level.
|
||||
* @return a singly-linked list of QRcode. On error, NULL is returned, and
|
||||
* errno is set to indicate the error. See Exceptions for the details.
|
||||
* @throw EINVAL invalid input object.
|
||||
* @throw ENOMEM unable to allocate memory for input objects.
|
||||
*/
|
||||
extern QRcode_List *QRcode_encodeDataStructured(int size, const unsigned char *data, int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return the number of symbols included in a QRcode_List.
|
||||
* @param qrlist a head entry of a QRcode_List.
|
||||
* @return number of symbols in the list.
|
||||
*/
|
||||
extern int QRcode_List_size(QRcode_List *qrlist);
|
||||
|
||||
/**
|
||||
* Free the QRcode_List.
|
||||
* @param qrlist a head entry of a QRcode_List.
|
||||
*/
|
||||
extern void QRcode_List_free(QRcode_List *qrlist);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* System utilities
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return a string that identifies the library version.
|
||||
* @param major_version major version number
|
||||
* @param minor_version minor version number
|
||||
* @param micro_version micro version number
|
||||
*/
|
||||
extern void QRcode_APIVersion(int *major_version, int *minor_version, int *micro_version);
|
||||
|
||||
/**
|
||||
* Return a string that identifies the library version.
|
||||
* @return a string identifies the library version. The string is held by the
|
||||
* library. Do NOT free it.
|
||||
*/
|
||||
extern char *QRcode_APIVersionString(void);
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
#ifndef _MSC_VER
|
||||
extern void QRcode_clearCache(void) __attribute__ ((deprecated));
|
||||
#else
|
||||
extern void QRcode_clearCache(void);
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* QRENCODE_H */
|
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Header for test use
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef QRENCODE_INNER_H
|
||||
#define QRENCODE_INNER_H
|
||||
|
||||
/**
|
||||
* This header file includes definitions for test use.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Raw code
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
int dataLength;
|
||||
int eccLength;
|
||||
unsigned char *data;
|
||||
unsigned char *ecc;
|
||||
} RSblock;
|
||||
|
||||
typedef struct {
|
||||
int version;
|
||||
int dataLength;
|
||||
int eccLength;
|
||||
unsigned char *datacode;
|
||||
unsigned char *ecccode;
|
||||
int b1;
|
||||
int blocks;
|
||||
RSblock *rsblock;
|
||||
int count;
|
||||
} QRRawCode;
|
||||
|
||||
extern QRRawCode *QRraw_new(QRinput *input);
|
||||
extern unsigned char QRraw_getCode(QRRawCode *raw);
|
||||
extern void QRraw_free(QRRawCode *raw);
|
||||
|
||||
/******************************************************************************
|
||||
* Raw code for Micro QR Code
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
int version;
|
||||
int dataLength;
|
||||
int eccLength;
|
||||
unsigned char *datacode;
|
||||
unsigned char *ecccode;
|
||||
RSblock *rsblock;
|
||||
int oddbits;
|
||||
int count;
|
||||
} MQRRawCode;
|
||||
|
||||
extern MQRRawCode *MQRraw_new(QRinput *input);
|
||||
extern unsigned char MQRraw_getCode(MQRRawCode *raw);
|
||||
extern void MQRraw_free(MQRRawCode *raw);
|
||||
|
||||
/******************************************************************************
|
||||
* Frame filling
|
||||
*****************************************************************************/
|
||||
extern unsigned char *FrameFiller_test(int version);
|
||||
extern unsigned char *FrameFiller_testMQR(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* QR-code encoding
|
||||
*****************************************************************************/
|
||||
extern QRcode *QRcode_encodeMask(QRinput *input, int mask);
|
||||
extern QRcode *QRcode_encodeMaskMQR(QRinput *input, int mask);
|
||||
extern QRcode *QRcode_new(int version, int width, unsigned char *data);
|
||||
|
||||
#endif /* QRENCODE_INNER_H */
|
1606
lib/awtk/awtk-examples/Moto_A58/3rd/awtk-widget-qr/src/qr/qrinput.c
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Input data chunk class
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef QRINPUT_H
|
||||
#define QRINPUT_H
|
||||
|
||||
#include "qrencode.h"
|
||||
#include "bitstream.h"
|
||||
|
||||
int QRinput_isSplittableMode(QRencodeMode mode);
|
||||
|
||||
/******************************************************************************
|
||||
* Entry of input data
|
||||
*****************************************************************************/
|
||||
typedef struct _QRinput_List QRinput_List;
|
||||
|
||||
struct _QRinput_List {
|
||||
QRencodeMode mode;
|
||||
int size; ///< Size of data chunk (byte).
|
||||
unsigned char *data; ///< Data chunk.
|
||||
BitStream *bstream;
|
||||
QRinput_List *next;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* Input Data
|
||||
*****************************************************************************/
|
||||
struct _QRinput {
|
||||
int version;
|
||||
QRecLevel level;
|
||||
QRinput_List *head;
|
||||
QRinput_List *tail;
|
||||
int mqr;
|
||||
int fnc1;
|
||||
unsigned char appid;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* Structured append input data
|
||||
*****************************************************************************/
|
||||
typedef struct _QRinput_InputList QRinput_InputList;
|
||||
|
||||
struct _QRinput_InputList {
|
||||
QRinput *input;
|
||||
QRinput_InputList *next;
|
||||
};
|
||||
|
||||
struct _QRinput_Struct {
|
||||
int size; ///< number of structured symbols
|
||||
int parity;
|
||||
QRinput_InputList *head;
|
||||
QRinput_InputList *tail;
|
||||
};
|
||||
|
||||
/**
|
||||
* Pack all bit streams padding bits into a byte array.
|
||||
* @param input input data.
|
||||
* @return padded merged byte stream
|
||||
*/
|
||||
extern unsigned char *QRinput_getByteStream(QRinput *input);
|
||||
|
||||
|
||||
extern int QRinput_estimateBitsModeNum(int size);
|
||||
extern int QRinput_estimateBitsModeAn(int size);
|
||||
extern int QRinput_estimateBitsMode8(int size);
|
||||
extern int QRinput_estimateBitsModeKanji(int size);
|
||||
|
||||
extern QRinput *QRinput_dup(QRinput *input);
|
||||
|
||||
extern const signed char QRinput_anTable[128];
|
||||
|
||||
/**
|
||||
* Look up the alphabet-numeric convesion table (see JIS X0510:2004, pp.19).
|
||||
* @param __c__ character
|
||||
* @return value
|
||||
*/
|
||||
#define QRinput_lookAnTable(__c__) \
|
||||
((__c__ & 0x80)?-1:QRinput_anTable[(int)__c__])
|
||||
|
||||
/**
|
||||
* Length of a standard mode indicator in bits.
|
||||
*/
|
||||
|
||||
#define MODE_INDICATOR_SIZE 4
|
||||
|
||||
/**
|
||||
* Length of a segment of structured-append header.
|
||||
*/
|
||||
#define STRUCTURE_HEADER_SIZE 20
|
||||
|
||||
/**
|
||||
* Maximum number of symbols in a set of structured-appended symbols.
|
||||
*/
|
||||
#define MAX_STRUCTURED_SYMBOLS 16
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
extern int QRinput_mergeBitStream(QRinput *input, BitStream *bstream);
|
||||
extern int QRinput_getBitStream(QRinput *input, BitStream *bstream);
|
||||
extern int QRinput_estimateBitStreamSize(QRinput *input, int version);
|
||||
extern int QRinput_splitEntry(QRinput_List *entry, int bytes);
|
||||
extern int QRinput_lengthOfCode(QRencodeMode mode, int version, int bits);
|
||||
extern int QRinput_insertStructuredAppendHeader(QRinput *input, int size, int index, unsigned char parity);
|
||||
#endif
|
||||
|
||||
#endif /* QRINPUT_H */
|