Merge branch 'printer' into 'v2.0'
Printer See merge request shaozhimin/kysdk-system!1
This commit is contained in:
commit
01fb8f4a11
|
@ -11,6 +11,14 @@ libkysdk-system (2.0.0.0) v101; urgency=medium
|
|||
[新增] 新增获取分辨率接口
|
||||
[新增] 新增根据进程号获取进程信息接口,根据进程名获取进程信息接口,获取进程全部信息接口
|
||||
[修改] 新增获取磁盘信息接口
|
||||
[新增] 获取本地打印机列表/获取可用打印机列表
|
||||
[新增] 设置打印参数
|
||||
[新增] 下载网络文件到本地
|
||||
[新增] 打印本地文件
|
||||
[新增] 获取打印机的状态
|
||||
[新增] 获取打印任务的状态
|
||||
[新增] 清除某个打印机的所有打印队列
|
||||
[新增] 从url中获取文件名的接口
|
||||
|
||||
-- shaozhimin <shaozhimin@kylinos.cn> Fri, 17 Oct 2022 09:22:40 +0800
|
||||
|
||||
|
|
|
@ -20,7 +20,10 @@ Build-Depends: debhelper-compat (= 12),
|
|||
libopencv-dev,
|
||||
libarchive-dev,
|
||||
libtesseract-dev,
|
||||
libcups2-dev,
|
||||
libcurl4-openssl-dev
|
||||
libxrandr-dev
|
||||
>>>>>>> debian/control
|
||||
Standards-Version: 4.4.1
|
||||
Homepage: http://gitlab2.kylin.com/kysdk/kysdk-system
|
||||
|
||||
|
@ -181,7 +184,9 @@ Depends: ${shlibs:Depends},
|
|||
libkysdk-log(>=1.2.0),
|
||||
libkysdk-config(>=1.2.0),
|
||||
systemd,
|
||||
libkysdk-systemcommon
|
||||
libkysdk-systemcommon,
|
||||
libcups2-dev,
|
||||
libcurl4-openssl-dev,
|
||||
Multi-Arch: same
|
||||
Description: 硬件信息获取库
|
||||
|
||||
|
@ -193,7 +198,8 @@ Depends: ${shlibs:Depends},
|
|||
libkysdk-hardware,
|
||||
libkysdk-log-dev(>=1.2.0),
|
||||
libkysdk-config-dev(>=1.2.0),
|
||||
libsystemd-dev
|
||||
libsystemd-dev,
|
||||
libcups2-dev
|
||||
Multi-Arch: same
|
||||
Description: 硬件信息获取库 - 开发库
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
usr/include/kysdk/kysdk-system/libkync.h
|
||||
usr/include/kysdk/kysdk-system/libkycpu.h
|
||||
usr/include/kysdk/kysdk-system/libkyprinter.h
|
||||
usr/include/kysdk/kysdk-system/libkybios.h
|
||||
usr/include/kysdk/kysdk-system/libkyboard.h
|
||||
usr/include/kysdk/kysdk-system/libkyusb.h
|
||||
|
|
|
@ -4,6 +4,14 @@ add_library(kyhw SHARED ${SOURCESCODE})
|
|||
set_target_properties(kyhw PROPERTIES VERSION 2.0.0 SOVERSION 1)
|
||||
add_executable(kync-test test/kync-test.c)
|
||||
add_executable(kycpu-test test/kycpu-test.c)
|
||||
add_executable(kyprinterlist-test test/kyprinterlist-test.c)
|
||||
add_executable(kyprinterprint-test test/kyprinterprint-test.c)
|
||||
# 额外链接的库在这一行
|
||||
target_link_libraries(kyhw kylog kyconf pthread systemd cups curl)
|
||||
target_link_libraries(kync-test kyhw)
|
||||
target_link_libraries(kycpu-test kyhw)
|
||||
target_link_libraries(kyprinterprint-test kyhw)
|
||||
target_link_libraries(kyprinterlist-test kyhw)
|
||||
add_executable(kyusb-test test/kyusb-test.c)
|
||||
add_executable(kybios-test test/kybios-test.c)
|
||||
add_executable(kyboard-test test/kyboard-test.c)
|
||||
|
@ -23,6 +31,9 @@ install(FILES libkync.h
|
|||
install(FILES libkycpu.h
|
||||
DESTINATION include/kysdk/kysdk-system)
|
||||
|
||||
install(FILES libkyprinter.h
|
||||
DESTINATION include/kysdk/kysdk-system)
|
||||
|
||||
install(FILES libkybios.h
|
||||
DESTINATION include/kysdk/kysdk-system)
|
||||
|
||||
|
|
|
@ -0,0 +1,511 @@
|
|||
#include "libkyprinter.h"
|
||||
#include <errno.h>
|
||||
#include <libkylog.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <syslog.h>
|
||||
#include <cups/cups.h>
|
||||
#include <cups/adminutil.h>
|
||||
#include <cups/ipp.h>
|
||||
#include <cups/ppd.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define _IPP_PRIVATE_STRUCTURES 1
|
||||
|
||||
cups_option_t *cups_options; // cups设置
|
||||
int num_options; // cups设置
|
||||
|
||||
char **kdk_printer_get_list()
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
cups_dest_t *dests = NULL;
|
||||
int num_dests = 0;
|
||||
int i = 0;
|
||||
char **printers = NULL;
|
||||
|
||||
num_dests = cupsGetDests(&dests);
|
||||
if (num_dests == 0 &&
|
||||
(cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
|
||||
cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED))
|
||||
{
|
||||
#ifdef PRT_DEBUG
|
||||
_cupsLangPrintf(stderr, "Printer: Error - add '/version=1.1' to server name.");
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < num_dests; i++)
|
||||
{
|
||||
printf("[%s] printer name is %s \n", __FUNCTION__, dests[i].name);
|
||||
char **tmp = realloc(printers, sizeof(char *) * i);
|
||||
printers = tmp;
|
||||
printers[i] = malloc(sizeof(char) * (strlen(dests[i].name) + 1));
|
||||
strcpy(printers[i], dests[i].name);
|
||||
}
|
||||
char **tmp = realloc(printers, sizeof(char *) * (i + 1));
|
||||
printers = tmp;
|
||||
printers[i] = NULL;
|
||||
cupsFreeDests(num_dests, dests);
|
||||
return printers;
|
||||
}
|
||||
|
||||
char **kdk_printer_get_available_list()
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
cups_dest_t *dests = NULL;
|
||||
int num_dests = 0;
|
||||
int i = 0, j = 0;
|
||||
char **printers = NULL;
|
||||
|
||||
num_dests = cupsGetDests(&dests);
|
||||
if (num_dests == 0 &&
|
||||
(cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
|
||||
cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED))
|
||||
{
|
||||
#ifdef PRT_DEBUG
|
||||
_cupsLangPrintf(stderr, "Printer: Error - add '/version=1.1' to server name.");
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < num_dests; i++)
|
||||
{
|
||||
if (kdk_printer_get_status(dests[i].name) == CUPS_PRINTER_STATE_IDLE)
|
||||
{
|
||||
printf("[%s] printer name is %s \n", __FUNCTION__, dests[i].name);
|
||||
char **tmp = realloc(printers, sizeof(char *) * j);
|
||||
printers = tmp;
|
||||
printers[j] = malloc(sizeof(char) * (strlen(dests[i].name) + 1));
|
||||
strcpy(printers[j], dests[i].name);
|
||||
//
|
||||
j++;
|
||||
}
|
||||
}
|
||||
char **tmp = realloc(printers, sizeof(char *) * (j + 1));
|
||||
printers = tmp;
|
||||
printers[j] = NULL;
|
||||
|
||||
cupsFreeDests(num_dests, dests);
|
||||
|
||||
return printers;
|
||||
}
|
||||
|
||||
int kdk_printer_remove_options()
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
if (num_options != 0 && cups_options != NULL)
|
||||
{
|
||||
cupsFreeOptions(num_options, cups_options);
|
||||
num_options = 0;
|
||||
cups_options = NULL;
|
||||
}
|
||||
printf("[%s] num_options = %d\n", __FUNCTION__, num_options);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kdk_printer_set_options(int number_up,
|
||||
const char *media,
|
||||
const char *number_up_layout, const char *sides)
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
kdk_printer_remove_options();
|
||||
cups_options = NULL;
|
||||
num_options = 0;
|
||||
|
||||
char NumberUp[2] = {0};
|
||||
|
||||
snprintf(NumberUp, 2, "%d", number_up);
|
||||
/* cups options */
|
||||
num_options = cupsAddOption("number-up", NumberUp, num_options, &cups_options);
|
||||
|
||||
num_options = cupsAddOption("media", media, num_options, &cups_options);
|
||||
|
||||
num_options = cupsAddOption("number-up-layout", number_up_layout, num_options, &cups_options);
|
||||
|
||||
num_options = cupsAddOption("sides", sides, num_options, &cups_options);
|
||||
}
|
||||
|
||||
int kdk_printer_print_local_file(const char *printername, char *filepath)
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
printf("[%s] printer_name: %s, file_path: %s\n", __FUNCTION__,
|
||||
printername,
|
||||
filepath);
|
||||
int jobid = 0;
|
||||
// stop状态禁止打印
|
||||
if (kdk_printer_get_status(printername) != CUPS_PRINTER_STATE_STOPPED)
|
||||
{
|
||||
jobid = cupsPrintFile(printername, filepath, "Print report", num_options, cups_options);
|
||||
//注意:这里没有设置格式的话会直接用默认格式,一般默认格式是单页打印
|
||||
// printf("[%s] num_options = %d,name = %s,value = %s",
|
||||
// __FUNCTION__,num_options,cups_options->name,cups_options->value);
|
||||
}
|
||||
return jobid;
|
||||
}
|
||||
|
||||
int kdk_printer_cancel_all_jobs(const char *printername)
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
int ret = cupsCancelJob(printername, CUPS_JOBID_ALL); // 1=success 0=fail
|
||||
if (ret == 0)
|
||||
{
|
||||
printf(LOG_ERR, "%s ,job_id = CUPS_JOBID_ALL, find err = %s ", __FUNCTION__, cupsLastErrorString());
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int /* O - 1 on match, 0 on no match */
|
||||
match_list(const char *list, /* I - List of names */
|
||||
const char *name) /* I - Name to find */
|
||||
{
|
||||
const char *nameptr; /* Pointer into name */
|
||||
/*
|
||||
* An empty list always matches...
|
||||
*/
|
||||
|
||||
if (!list || !*list)
|
||||
return (1);
|
||||
if (!name)
|
||||
return (0);
|
||||
while (*list)
|
||||
{
|
||||
/*
|
||||
* Skip leading whitespace and commas...
|
||||
*/
|
||||
while (isspace(*list & 255) || *list == ',')
|
||||
list++;
|
||||
if (!*list)
|
||||
break;
|
||||
/*
|
||||
* Compare names...
|
||||
*/
|
||||
for (nameptr = name;
|
||||
*nameptr && *list && tolower(*nameptr & 255) == tolower(*list & 255);
|
||||
nameptr++, list++)
|
||||
;
|
||||
if (!*nameptr && (!*list || *list == ',' || isspace(*list & 255)))
|
||||
return (1);
|
||||
while (*list && !isspace(*list & 255) && *list != ',')
|
||||
list++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int /* O - 0 on success, 1 on fail */
|
||||
_show_printer_state(const char *printers /* I - Destinations */
|
||||
// char* buf, /* I - Number of user-defined dests */
|
||||
) /* I - User-defined destinations */
|
||||
{
|
||||
int i; /* Looping var */
|
||||
ipp_t *request, /* IPP Request */
|
||||
*response; /* IPP Response */
|
||||
ipp_attribute_t *attr; /* Current attribute */
|
||||
time_t ptime; /* Printer state time */
|
||||
|
||||
const char *printer, /* Printer name */
|
||||
*device; /* Printer device URI */
|
||||
ipp_pstate_t pstate;
|
||||
int state_code = 0;
|
||||
static const char *pattrs[] = /* Attributes we need for printers... */
|
||||
{
|
||||
"printer-name",
|
||||
"printer-state"};
|
||||
|
||||
#ifdef PRT_DEBUG
|
||||
printf(("show_devices(printers=\"%s\")\n", printers));
|
||||
#endif
|
||||
if (printers != NULL && !strcmp(printers, "all"))
|
||||
printers = NULL;
|
||||
|
||||
/*
|
||||
* Build a CUPS_GET_PRINTERS request, which requires the following
|
||||
* attributes:
|
||||
*
|
||||
* attributes-charset
|
||||
* attributes-natural-language
|
||||
* requested-attributes
|
||||
* requesting-user-name
|
||||
*/
|
||||
|
||||
request = ippNewRequest(CUPS_GET_PRINTERS);
|
||||
|
||||
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
||||
"requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
|
||||
NULL, pattrs);
|
||||
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
|
||||
NULL, cupsUser());
|
||||
|
||||
/*
|
||||
* Do the request and get back a response...
|
||||
*/
|
||||
|
||||
response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/");
|
||||
|
||||
if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
|
||||
cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED)
|
||||
{
|
||||
#ifdef PRT_DEBUG
|
||||
_cupsLangPrintf(stderr,
|
||||
"%s: Error - add '/version=1.1' to server name.",
|
||||
"lpstat");
|
||||
#endif
|
||||
ippDelete(response);
|
||||
return (1);
|
||||
}
|
||||
else if (cupsLastError() > IPP_STATUS_OK_CONFLICTING)
|
||||
{
|
||||
#ifdef PRT_DEBUG
|
||||
_cupsLangPrintf(stderr, "lpstat: %s", cupsLastErrorString());
|
||||
#endif
|
||||
ippDelete(response);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (response)
|
||||
{
|
||||
/*
|
||||
* Loop through the printers returned in the list and display
|
||||
* their devices...
|
||||
*/
|
||||
attr = ippFirstAttribute(response);
|
||||
for (; attr != NULL; attr = ippNextAttribute(response))
|
||||
{
|
||||
/*
|
||||
* Skip leading attributes until we hit a job...
|
||||
*/
|
||||
|
||||
while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER)
|
||||
attr = ippNextAttribute(response);
|
||||
|
||||
if (attr == NULL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Pull the needed attributes from this job...
|
||||
*/
|
||||
printer = NULL;
|
||||
pstate = IPP_PRINTER_IDLE;
|
||||
while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_PRINTER)
|
||||
{
|
||||
const char *attr_name = ippGetName(attr);
|
||||
ipp_tag_t value_tag = ippGetValueTag(attr);
|
||||
if (!strcmp(attr_name, "printer-name") &&
|
||||
value_tag == IPP_TAG_NAME)
|
||||
printer = ippGetString(attr, 0, NULL);
|
||||
else if (!strcmp(attr_name, "printer-state") &&
|
||||
value_tag == IPP_TAG_ENUM)
|
||||
{
|
||||
pstate = (ipp_pstate_t)ippGetInteger(attr, 0);
|
||||
// printf("statecode: %d\n",ippGetInteger(attr,0));
|
||||
}
|
||||
|
||||
attr = ippNextAttribute(response);
|
||||
}
|
||||
|
||||
/*
|
||||
* See if we have everything needed...
|
||||
*/
|
||||
|
||||
if (printer == NULL)
|
||||
{
|
||||
if (attr == NULL)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
if (match_list(printers, printer))
|
||||
{
|
||||
switch (pstate)
|
||||
{
|
||||
case IPP_PRINTER_IDLE:
|
||||
state_code = CUPS_PRINTER_STATE_IDLE;
|
||||
// snprintf(buf,buf_len,PRINTER_STATE_IDLE);
|
||||
break;
|
||||
case IPP_PRINTER_PROCESSING:
|
||||
state_code = CUPS_PRINTER_STATE_PROCESSING;
|
||||
// snprintf(buf,buf_len,PRINTER_STATE_PROCESSING);
|
||||
break;
|
||||
case IPP_PRINTER_STOPPED:
|
||||
state_code = CUPS_PRINTER_STATE_STOPPED;
|
||||
// snprintf(buf,buf_len,PRINTER_STATE_STOPPED);
|
||||
break;
|
||||
case IPP_PRINTER_BUSY:
|
||||
state_code = CUPS_PRINTER_STATE_PROCESSING;
|
||||
// snprintf(buf,buf_len,PRINTER_STATE_PROCESSING);
|
||||
break;
|
||||
default:
|
||||
state_code = CUPS_PRINTER_STATE_STOPPED;
|
||||
// snprintf(buf,buf_len,PRINTER_STATE_STOPPED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (attr == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
ippDelete(response);
|
||||
}
|
||||
|
||||
return state_code;
|
||||
}
|
||||
|
||||
int kdk_printer_get_status(const char *printername)
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
http_t *http; /* Connection to server */
|
||||
int ret;
|
||||
if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
|
||||
cupsEncryption())) != NULL)
|
||||
{
|
||||
httpClose(http);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
return _show_printer_state(printername);
|
||||
}
|
||||
|
||||
size_t processdata(void *buffer, size_t size, size_t nmemb, void *user_p)
|
||||
{
|
||||
return nmemb;
|
||||
}
|
||||
|
||||
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
{
|
||||
size_t written = fwrite(ptr, size, nmemb, stream);
|
||||
return written;
|
||||
}
|
||||
//获取url内的文件名
|
||||
void kdk_printer_get_filename(const char *url, char *filename)
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
int len = strlen(url);
|
||||
int i;
|
||||
for (i = (len - 1); i >= 0; i--)
|
||||
{
|
||||
if ((url[i] == '\\') || (url[i] == '/'))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
strcpy(filename, &url[i + 1]);
|
||||
return;
|
||||
}
|
||||
//检查url是否存在
|
||||
bool check_url(char *url)
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
// 获得一个CURL会话,进行网络操作
|
||||
CURL *handle = curl_easy_init();
|
||||
if (NULL != handle && NULL != url)
|
||||
{
|
||||
// 设置本次会话的参数
|
||||
// URL,就是我们要验证的网址
|
||||
curl_easy_setopt(handle, CURLOPT_URL, url);
|
||||
// 设置连接超时
|
||||
curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
// 只是获取HTML的header
|
||||
curl_easy_setopt(handle, CURLOPT_HEADER, true);
|
||||
curl_easy_setopt(handle, CURLOPT_NOBODY, true);
|
||||
// 设置最大重定向数为0,不允许页面重定向
|
||||
curl_easy_setopt(handle, CURLOPT_MAXREDIRS, 0);
|
||||
// 设置一个空的写入函数,屏蔽屏幕输出
|
||||
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, &processdata);
|
||||
|
||||
// 以上面设置的参数执行这个会话,向服务器发起请求
|
||||
curl_easy_perform(handle);
|
||||
// 获取HTTP的状态代码
|
||||
// 根据代码判断网址是否有效
|
||||
int retcode = 0;
|
||||
curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &retcode);
|
||||
bool res = false;
|
||||
// 如果HTTP反应代码为200,表示网址有效
|
||||
if (200 == retcode)
|
||||
{
|
||||
res = true;
|
||||
}
|
||||
// 执行会话的清理工作
|
||||
curl_easy_cleanup(handle);
|
||||
|
||||
return res;
|
||||
}
|
||||
else // 无法验证
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//下载url到文件
|
||||
int download_file(char *url, const char *savefile)
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
CURL *curl;
|
||||
FILE *fp;
|
||||
CURLcode res;
|
||||
printf("[%s] url = %s \n", __FUNCTION__, url);
|
||||
printf("[%s] savefile = %s \n", __FUNCTION__, savefile);
|
||||
curl = curl_easy_init();
|
||||
if (curl)
|
||||
{
|
||||
fp = fopen(savefile, "wb");
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
|
||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L); // timeout for the connect phase
|
||||
/* abort if slower than 1 bytes/sec during 6 seconds */
|
||||
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 6);
|
||||
res = curl_easy_perform(curl);
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
fclose(fp);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int kdk_printer_print_download_remote_file(const char *url, const char *filepath)
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
int res = -1;
|
||||
|
||||
bool available = check_url(url);
|
||||
if (available)
|
||||
{
|
||||
res = download_file(url, filepath);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s seems to be unavailable.\n", url);
|
||||
}
|
||||
printf("res = %d.\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
int kdk_printer_get_job_status(const char *printername, int jobid)
|
||||
{
|
||||
printf("[%s] Start\n", __FUNCTION__);
|
||||
cups_job_t *jobs = NULL;
|
||||
int i;
|
||||
int number_jobs;
|
||||
int ret;
|
||||
|
||||
number_jobs = cupsGetJobs(&jobs, printername, 1, CUPS_WHICHJOBS_ALL);
|
||||
ipp_jstate_t state = 0;
|
||||
|
||||
for (i = 0; i < number_jobs; i++)
|
||||
{
|
||||
if (jobs[i].id == jobid)
|
||||
{
|
||||
state = jobs[i].state;
|
||||
printf("[%s] job state is %d\n", __FUNCTION__, jobs[i].state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cupsFreeJobs(number_jobs, jobs);
|
||||
|
||||
return state;
|
||||
}
|
|
@ -0,0 +1,258 @@
|
|||
#ifndef KDK_SYSTEM_HW_NWCARD_H__
|
||||
#define KDK_SYSTEM_HW_NWCARD_H__
|
||||
//打印机状态
|
||||
#define CUPS_PRINTER_STATE_BUSY 6 //"Busy"
|
||||
#define CUPS_PRINTER_STATE_STOPPED 4 //"Stop"
|
||||
#define CUPS_PRINTER_STATE_IDLE 2 //"Idle"
|
||||
#define CUPS_PRINTER_STATE_PROCESSING 3 //"Processing"
|
||||
|
||||
//打印任务状态
|
||||
#define IPP_JOB_PENDING 3 //挂起等待打印
|
||||
#define IPP_JOB_HELD 4 //等待打印
|
||||
#define IPP_JOB_PROCESSING 5 //打印中
|
||||
#define IPP_JOB_STOPPED 6 //停止
|
||||
#define IPP_JOB_CANCELED 7 //取消
|
||||
#define IPP_JOB_ABORTED 8 //由于错误跳过该打印任务
|
||||
#define IPP_JOB_COMPLETED 9 //正常完成
|
||||
|
||||
//下载状态
|
||||
// typedef enum {
|
||||
// CURLE_OK = 0,
|
||||
// CURLE_UNSUPPORTED_PROTOCOL, /* 1 */
|
||||
// CURLE_FAILED_INIT, /* 2 */
|
||||
// CURLE_URL_MALFORMAT, /* 3 */
|
||||
// CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for
|
||||
// 7.17.0, reused in April 2011 for 7.21.5] */
|
||||
// CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
|
||||
// CURLE_COULDNT_RESOLVE_HOST, /* 6 */
|
||||
// CURLE_COULDNT_CONNECT, /* 7 */
|
||||
// CURLE_WEIRD_SERVER_REPLY, /* 8 */
|
||||
// CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server
|
||||
// due to lack of access - when login fails
|
||||
// this is not returned. */
|
||||
// CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for
|
||||
// 7.15.4, reused in Dec 2011 for 7.24.0]*/
|
||||
// CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */
|
||||
// CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server
|
||||
// [was obsoleted in August 2007 for 7.17.0,
|
||||
// reused in Dec 2011 for 7.24.0]*/
|
||||
// CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
|
||||
// CURLE_FTP_WEIRD_227_FORMAT, /* 14 */
|
||||
// CURLE_FTP_CANT_GET_HOST, /* 15 */
|
||||
// CURLE_HTTP2, /* 16 - A problem in the http2 framing layer.
|
||||
// [was obsoleted in August 2007 for 7.17.0,
|
||||
// reused in July 2014 for 7.38.0] */
|
||||
// CURLE_FTP_COULDNT_SET_TYPE, /* 17 */
|
||||
// CURLE_PARTIAL_FILE, /* 18 */
|
||||
// CURLE_FTP_COULDNT_RETR_FILE, /* 19 */
|
||||
// CURLE_OBSOLETE20, /* 20 - NOT USED */
|
||||
// CURLE_QUOTE_ERROR, /* 21 - quote command failure */
|
||||
// CURLE_HTTP_RETURNED_ERROR, /* 22 */
|
||||
// CURLE_WRITE_ERROR, /* 23 */
|
||||
// CURLE_OBSOLETE24, /* 24 - NOT USED */
|
||||
// CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */
|
||||
// CURLE_READ_ERROR, /* 26 - couldn't open/read from file */
|
||||
// CURLE_OUT_OF_MEMORY, /* 27 */
|
||||
// /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
|
||||
// instead of a memory allocation error if CURL_DOES_CONVERSIONS
|
||||
// is defined
|
||||
// */
|
||||
// CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */
|
||||
// CURLE_OBSOLETE29, /* 29 - NOT USED */
|
||||
// CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */
|
||||
// CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */
|
||||
// CURLE_OBSOLETE32, /* 32 - NOT USED */
|
||||
// CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */
|
||||
// CURLE_HTTP_POST_ERROR, /* 34 */
|
||||
// CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */
|
||||
// CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */
|
||||
// CURLE_FILE_COULDNT_READ_FILE, /* 37 */
|
||||
// CURLE_LDAP_CANNOT_BIND, /* 38 */
|
||||
// CURLE_LDAP_SEARCH_FAILED, /* 39 */
|
||||
// CURLE_OBSOLETE40, /* 40 - NOT USED */
|
||||
// CURLE_FUNCTION_NOT_FOUND, /* 41 - NOT USED starting with 7.53.0 */
|
||||
// CURLE_ABORTED_BY_CALLBACK, /* 42 */
|
||||
// CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */
|
||||
// CURLE_OBSOLETE44, /* 44 - NOT USED */
|
||||
// CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */
|
||||
// CURLE_OBSOLETE46, /* 46 - NOT USED */
|
||||
// CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */
|
||||
// CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */
|
||||
// CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */
|
||||
// CURLE_OBSOLETE50, /* 50 - NOT USED */
|
||||
// CURLE_OBSOLETE51, /* 51 - NOT USED */
|
||||
// CURLE_GOT_NOTHING, /* 52 - when this is a specific error */
|
||||
// CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */
|
||||
// CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as
|
||||
// default */
|
||||
// CURLE_SEND_ERROR, /* 55 - failed sending network data */
|
||||
// CURLE_RECV_ERROR, /* 56 - failure in receiving network data */
|
||||
// CURLE_OBSOLETE57, /* 57 - NOT IN USE */
|
||||
// CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */
|
||||
// CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */
|
||||
// CURLE_PEER_FAILED_VERIFICATION, /* 60 - peer's certificate or fingerprint
|
||||
// wasn't verified fine */
|
||||
// CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */
|
||||
// CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */
|
||||
// CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */
|
||||
// CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */
|
||||
// CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind
|
||||
// that failed */
|
||||
// CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */
|
||||
// CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not
|
||||
// accepted and we failed to login */
|
||||
// CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */
|
||||
// CURLE_TFTP_PERM, /* 69 - permission problem on server */
|
||||
// CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */
|
||||
// CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */
|
||||
// CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */
|
||||
// CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */
|
||||
// CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */
|
||||
// CURLE_CONV_FAILED, /* 75 - conversion failed */
|
||||
// CURLE_CONV_REQD, /* 76 - caller must register conversion
|
||||
// callbacks using curl_easy_setopt options
|
||||
// CURLOPT_CONV_FROM_NETWORK_FUNCTION,
|
||||
// CURLOPT_CONV_TO_NETWORK_FUNCTION, and
|
||||
// CURLOPT_CONV_FROM_UTF8_FUNCTION */
|
||||
// CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing
|
||||
// or wrong format */
|
||||
// CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */
|
||||
// CURLE_SSH, /* 79 - error from the SSH layer, somewhat
|
||||
// generic so the error message will be of
|
||||
// interest when this has happened */
|
||||
|
||||
// CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL
|
||||
// connection */
|
||||
// CURLE_AGAIN, /* 81 - socket is not ready for send/recv,
|
||||
// wait till it's ready and try again (Added
|
||||
// in 7.18.2) */
|
||||
// CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or
|
||||
// wrong format (Added in 7.19.0) */
|
||||
// CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in
|
||||
// 7.19.0) */
|
||||
// CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */
|
||||
// CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */
|
||||
// CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */
|
||||
// CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */
|
||||
// CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */
|
||||
// CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
|
||||
// session will be queued */
|
||||
// CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not
|
||||
// match */
|
||||
// CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */
|
||||
// CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer
|
||||
// */
|
||||
// CURLE_RECURSIVE_API_CALL, /* 93 - an api function was called from
|
||||
// inside a callback */
|
||||
// CURLE_AUTH_ERROR, /* 94 - an authentication function returned an
|
||||
// error */
|
||||
// CURLE_HTTP3, /* 95 - An HTTP/3 layer problem */
|
||||
// CURL_LAST /* never use! */
|
||||
// } CURLcode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 获取本地的所有打印机(包含可用打印机和不可用打印机)
|
||||
*
|
||||
* @return char** 网卡名称列表,由NULL字符串表示结尾;由alloc生成,需要被kdk_printer_freeall回收;若获取出错,返回NULL;
|
||||
*/
|
||||
extern char** kdk_printer_get_list();
|
||||
|
||||
/**
|
||||
* @brief 获取本地的所有可用打印机(打印机处于idle状态)
|
||||
*
|
||||
* @return char** 网卡名称列表,由NULL字符串表示结尾;由alloc生成,需要被kdk_printer_freeall回收;若获取出错,返回NULL;
|
||||
*/
|
||||
extern char** kdk_printer_get_available_list();
|
||||
|
||||
|
||||
/**
|
||||
* @brief 设置打印参数,每次设置会清除之前设置打印参数,这个设置是全局设置,设置了之后所有打印机都会用这个参数进行打印
|
||||
*
|
||||
* @param printername 打印机名,kdk_printer_get_list返回的值
|
||||
* @param number_up cups属性,一张纸打印几页,如2 4等
|
||||
* @param media cups属性,纸张类型,如A4
|
||||
* @param number_up_layout cups属性,如lrtb
|
||||
* @param sides cups属性,单面如one-sided,双面如two-sided-long-edge(长边翻转),two-sided-short-edge(短边翻转)
|
||||
*
|
||||
* @return 无
|
||||
*/
|
||||
extern void kdk_printer_set_options(int number_up,const char *media,const char *number_up_layout,const char *sides);
|
||||
|
||||
/**
|
||||
* @brief 下载网络文件
|
||||
*
|
||||
* @param url 要打印的url
|
||||
* @param filepath 保存的文件路径
|
||||
*
|
||||
* @return 打印作业的id
|
||||
*
|
||||
*/
|
||||
extern int kdk_printer_print_download_remote_file(const char *url, const char *filepath);
|
||||
|
||||
/**
|
||||
* @brief 打印本地文件
|
||||
*
|
||||
* @param printername 打印机名,kdk_printer_get_list返回的值
|
||||
* @param filepath 文件绝对路径
|
||||
*
|
||||
* @return 打印作业的id
|
||||
*
|
||||
* @notice 虽然支持多种格式的打印,但是打印除pdf之外的格式打印的效果都不够好,建议打印pdf格式的文件
|
||||
* 打印机处于stop状态函数返回0
|
||||
* 格式不对的文件可以成功创建打印任务,但是打印不出来。什么叫格式不对,举个例子,比如当前要打印日志文件a.log,
|
||||
* 然后把a.log改名叫a.pdf,这个时候a.pdf就变成了格式不对的文件,打印不出来了
|
||||
*
|
||||
*/
|
||||
extern int kdk_printer_print_local_file(const char *printername, char *filepath);
|
||||
|
||||
/**
|
||||
* @brief 清除某个打印机的所有打印队列
|
||||
*
|
||||
* @param printername 打印机名,kdk_printer_get_list返回的值
|
||||
*
|
||||
* @return 成功返回0,失败返回-1
|
||||
*
|
||||
* @notice 同kdk_printer_print_local_file
|
||||
*/
|
||||
extern int kdk_printer_cancel_all_jobs(const char *printername);
|
||||
|
||||
/**
|
||||
* @brief 获取当前打印机状态(状态不是实时更新)
|
||||
*
|
||||
* @param printername 打印机名,kdk_printer_get_list返回的值
|
||||
*
|
||||
* @return 状态码
|
||||
*/
|
||||
extern int kdk_printer_get_status(const char *printername);
|
||||
|
||||
/**
|
||||
* @brief 获取当前打印任务状态(发送打印任务之后下需要等待一会再获取状态,状态不是实时更新)
|
||||
*
|
||||
* @param printername 打印机名,kdk_printer_get_list返回的值
|
||||
*
|
||||
* @return 状态码
|
||||
*/
|
||||
extern int kdk_printer_get_job_status(const char *printername, int jobid);
|
||||
|
||||
/**
|
||||
* @brief 获取url内的文件名
|
||||
*
|
||||
* @param url
|
||||
* @param filename 解析出来的文件名
|
||||
*
|
||||
* @return 无
|
||||
*/
|
||||
extern void kdk_printer_get_filename(const char *url, char *filename);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
|
@ -0,0 +1,29 @@
|
|||
#include "../libkyprinter.h"
|
||||
#include "../libkync.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int index = 0;
|
||||
//获取全部打印机列表
|
||||
char **printers = kdk_printer_get_list();
|
||||
while (printers[index])
|
||||
{
|
||||
int status = kdk_printer_get_status(printers[index]);
|
||||
printf("%zd: %s , %d\n", index + 1, printers[index], status);
|
||||
index++;
|
||||
}
|
||||
kdk_nc_freeall(printers);
|
||||
//获取可用打印机列表
|
||||
index = 0;
|
||||
char **available_printers = kdk_printer_get_list();
|
||||
while (available_printers[index])
|
||||
{
|
||||
int status = kdk_printer_get_status(available_printers[index]);
|
||||
printf("%zd: %s , %d\n", index + 1, available_printers[index], status);
|
||||
index++;
|
||||
}
|
||||
kdk_nc_freeall(available_printers);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
#include "../libkyprinter.h"
|
||||
#include "../libkync.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int index = 0;
|
||||
//获取打印机列表
|
||||
char **printers = kdk_printer_get_available_list();
|
||||
while (printers[index])
|
||||
{
|
||||
printf("%zd: %s\n", index + 1, printers[index]);
|
||||
|
||||
//取消当前打印机所有打印任务
|
||||
kdk_printer_cancel_all_jobs(printers[index]);
|
||||
|
||||
//获取url对应的文件名
|
||||
char *url = "http://www.cztouch.com/upfiles/soft/testpdf.pdf";
|
||||
int res = -1;
|
||||
char *filename = (char *)malloc(sizeof(url)); //申请一个缓冲区,存放接收到的文件内容
|
||||
memset(filename, 0, sizeof(url));
|
||||
kdk_printer_get_filename(url, filename); //从完整路径名中解析出文件名称,例如:/home/test/abc.txt,解析完成后为abc.txt
|
||||
printf("filename = %s\n", filename);
|
||||
|
||||
//设置打印参数
|
||||
kdk_printer_set_options(2, "A4", "lrtb", "two-sided-long-edge");
|
||||
|
||||
//下载
|
||||
res = kdk_printer_print_download_remote_file(url, filename);
|
||||
printf("[%s] res = %d\n", __FUNCTION__, res);
|
||||
printf("[%s] filepath = %s\n", __FUNCTION__, filename);
|
||||
|
||||
//打印
|
||||
int job_id = kdk_printer_print_local_file(printers[index], filename);
|
||||
if (job_id == 0)
|
||||
{
|
||||
//打印失败
|
||||
printf("[%s] create print job fail\n", __FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
//打印成功,等待一会获取任务状态
|
||||
sleep(10);
|
||||
int status = kdk_printer_get_job_status(printers[index], job_id);
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
kdk_nc_freeall(printers);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue