4 * Copyright 2012-2013 Samsung Electronics Co., Ltd
6 * Licensed under the Flora License, Version 1.1 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://floralicense.org/license/
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 #include <sys/types.h>
27 #include "pt_common.h"
29 #include "pt_printer.h"
32 #define PREFERENCE_DEFAULT_PRINTER_NAME "mobileprint_default_printer_name"
33 #define PREFERENCE_DEFAULT_PRINTER_ADDRESS "mobileprint_default_printer_address"
34 #define PREFERENCE_DEFAULT_PRINTER_MFG "mobileprint_default_printer_mfg"
35 #define PREFERENCE_DEFAULT_PRINTER_MDL "mobileprint_default_printer_mdl"
37 static void g_printer_data_destroy(gconstpointer a)
42 static gboolean __printer_compare(gconstpointer a, gconstpointer b)
44 pt_printer_info_t *printer_a = (pt_printer_info_t *)a;
45 pt_printer_info_t *printer_b = (pt_printer_info_t *)b;
46 PT_RETV_IF(a==NULL || b==NULL, FALSE, "a or b is NULL");
48 if (strcmp(printer_a->device_uri, printer_b->device_uri) == 0) {
50 } else if (!strncmp(printer_a->device_uri, "dnssd:",6) && !strncmp(printer_b->device_uri, "dnssd:",6)) {
51 if (strcmp(printer_a->device_info, printer_b->device_info) == 0) {
60 static pt_printer_info_t *pt_util_make_printer_info(const char *device_info,
61 const char *device_make_and_model,
62 const char *device_uri)
64 pt_printer_info_t *localdetail = NULL;
65 localdetail = (pt_printer_info_t *)malloc(sizeof(pt_printer_info_t));
66 PT_RETV_IF(localdetail == NULL, NULL, "localdetail is NULL");
67 memset(localdetail, 0, sizeof(pt_printer_info_t));
69 char *device_mfg = NULL;
70 char *device_mdl = NULL;
71 char *device_name = NULL;
73 ret = pt_utils_get_mfg_mdl(device_make_and_model, &device_mfg, &device_mdl);
74 if (ret != PT_ERR_NONE) {
75 PT_IF_FREE_MEM(localdetail);
76 PT_IF_FREE_MEM(device_mfg);
77 PT_IF_FREE_MEM(device_mdl);
78 PT_DEBUG("ERROR : %d in pt_utils_get_mfg_mdl", ret);
81 if (device_mfg == NULL) {
82 PT_IF_FREE_MEM(localdetail);
83 PT_IF_FREE_MEM(device_mdl);
84 PT_DEBUG("device_mfg == NULL");
87 if (device_mdl == NULL) {
88 PT_IF_FREE_MEM(localdetail);
89 PT_IF_FREE_MEM(device_mfg);
90 PT_DEBUG("device_mdl == NULL");
94 device_name = calloc(1, strlen(device_mfg)+strlen(device_mdl)+2);
95 if (device_name == NULL) {
96 PT_IF_FREE_MEM(localdetail);
97 PT_IF_FREE_MEM(device_mfg);
98 PT_IF_FREE_MEM(device_mdl);
99 PT_DEBUG("No memory. calloc failed");
103 strncat(device_name,device_mfg,strlen(device_mfg));
104 strncat(device_name," ",1);
105 strncat(device_name,device_mdl,strlen(device_mdl));
107 strncpy(localdetail->model_name, device_mdl, sizeof(localdetail->model_name)-1);
108 strncpy(localdetail->manufacturer, device_mfg, sizeof(localdetail->manufacturer)-1);
109 strncpy(localdetail->product_ui_name, device_name, sizeof(localdetail->product_ui_name)-1);
110 __standardization(localdetail->product_ui_name);
111 strncpy(localdetail->device_uri, device_uri, sizeof(localdetail->device_uri)-1);
112 strncpy(localdetail->device_info, device_info, sizeof(localdetail->device_info)-1);
114 PT_IF_FREE_MEM(device_mfg);
115 PT_IF_FREE_MEM(device_mdl);
116 PT_IF_FREE_MEM(device_name);
121 static void pt_util_add_printer_to_hashlist(GHashTable *printer_hashlist, pt_printer_info_t *printer)
123 PT_RET_IF(printer == NULL, "printer is NULL");
124 PT_RET_IF(printer_hashlist == NULL, "printer_hashlist is NULL");
126 pt_printer_info_t *tempdetail = NULL;
127 tempdetail = (pt_printer_info_t *) g_hash_table_lookup(printer_hashlist, printer);
129 if (NULL == tempdetail) {
130 g_hash_table_insert(printer_hashlist, printer, printer);
131 PT_DEBUG("Added printer_hashlist: %s", printer->device_uri);
133 if (strstr(tempdetail->device_uri, "_printer.") && strstr(printer->device_uri, "_ipp.")) {
134 g_hash_table_replace(printer_hashlist, printer, printer);
135 PT_DEBUG("Replaced printer_hashlist: %s", printer->device_uri);
136 } else if (strstr(tempdetail->device_uri, "_pdl-datastream.") &&
137 (strstr(printer->device_uri, "_printer.") || strstr(printer->device_uri, "_ipp."))) {
138 g_hash_table_replace(printer_hashlist, printer, printer);
139 PT_DEBUG("Replaced printer_hashlist: %s", printer->device_uri);
144 static int compare_printer(pt_printer_mgr_t *printer_a, pt_printer_mgr_t *printer_b)
146 if (printer_a->is_ppd_exist == TRUE && printer_b->is_ppd_exist == FALSE) {
148 } else if (printer_a->is_ppd_exist == FALSE && printer_b->is_ppd_exist == TRUE) {
151 if (strcmp(printer_a->name, printer_b->name) != 0) {
152 return strcmp(printer_a->name, printer_b->name);
155 return strcmp(printer_a->address, printer_b->address);
160 static void pt_util_append_printer(pt_search_data_t *search_data, GHashTable *printer_hashlist)
164 pt_printer_info_t *printer_temp = NULL;
165 Eina_Compare_Cb cmp_func = (Eina_Compare_Cb)compare_printer;
167 g_hash_table_iter_init(&iter, printer_hashlist);
168 while (g_hash_table_iter_next(&iter, &key, &value)) {
169 printer_temp = (pt_printer_info_t *)malloc(sizeof(pt_printer_info_t));
170 PT_RET_IF(printer_temp == NULL, "printer_temp is NULL");
171 memset(printer_temp, 0, sizeof(pt_printer_info_t));
172 memcpy(printer_temp, value, sizeof(pt_printer_info_t));
173 search_data->pt_local_list = eina_list_append(search_data->pt_local_list, (pt_printer_info_t *)printer_temp);
174 if (eina_error_get()) {
175 PT_DEBUG("Failed to add eina_list for search_data->pt_local_list");
179 /* add searched printer */
180 Eina_List *cursor = NULL;
181 pt_printer_info_t *it = NULL;
182 pt_printer_mgr_t *detail = NULL;
184 //TODO:: free ( search_data->response_data.printerlist ); -- dwmax
185 search_data->response_data.printerlist = NULL;
187 Eina_Bool bfirst = EINA_TRUE;
188 /* add printer to response list */
189 EINA_LIST_FOREACH(search_data->pt_local_list, cursor, it) {
190 detail = (pt_printer_mgr_t *)malloc(sizeof(pt_printer_mgr_t));
191 if (detail != NULL) {
192 memset(detail, 0, sizeof(pt_printer_mgr_t));
194 strncpy(detail->name, it->product_ui_name, PT_MAX_LENGTH -1);
195 strncpy(detail->address, it->device_uri, PT_MAX_LENGTH -1);
196 strncpy(detail->mdl, it->model_name, PT_MAX_LENGTH -1);
197 strncpy(detail->mfg, it->manufacturer, PT_MAX_LENGTH -1);
198 PT_DEBUG("product %s",it->product_ui_name);
199 PT_DEBUG("url %s",it->device_uri);
200 PT_DEBUG("mdl %s",it->model_name);
201 PT_DEBUG("mfg %s",it->manufacturer);
203 if (EINA_TRUE == bfirst) {
207 if (pt_get_printer_ppd(detail) != PT_ERR_NONE) {
208 //Unsupported Printer
209 detail->is_ppd_exist = FALSE;
211 detail->is_ppd_exist = TRUE;
214 // search_data->response_data.printerlist = eina_list_append(search_data->response_data.printerlist, detail);
215 search_data->response_data.printerlist = eina_list_sorted_insert(search_data->response_data.printerlist, cmp_func,detail);
216 if (eina_error_get()) {
217 PT_DEBUG("Failed to add eina_list for search_data->response_data.printerlist");
224 static void searching_thread_notify_cb(void *data, Ecore_Thread *thread, void *msg_data)
226 PRINT_SERVICE_FUNC_ENTER;
227 PT_RET_IF(data == NULL, "data is NULL");
228 PT_RET_IF(msg_data == NULL, "msg_data is NULL");
229 PT_DEBUG("Thread is sent msg successfully.");
231 pt_search_data_t *search_data = NULL;
232 ipp_t *response = NULL;
234 search_data = (pt_search_data_t *)data;
235 response = (ipp_t *)msg_data;
237 PT_RET_IF(search_data->user_cb == NULL, "user_cb is NULL");
239 GHashTable *printer_hashlist = g_hash_table_new_full(g_str_hash, __printer_compare, NULL, (GDestroyNotify)g_printer_data_destroy);
241 ipp_attribute_t *attr = NULL;
242 const char *device_uri = NULL; /* device-uri attribute value */
243 const char *device_info = NULL; /* device-info value */
244 const char *device_make_and_model = NULL; /* device-make-and-model value */
246 for (attr = ippFirstAttribute(response); attr != NULL; attr = ippNextAttribute(response)) {
249 if (ippGetGroupTag(attr) == IPP_TAG_ZERO) {
250 PT_DEBUG("-----------------------------------------");
251 } else if (ippGetGroupTag(attr) != IPP_TAG_PRINTER) {
253 } else if (!strcmp(ippGetName(attr), "device-info") && ippGetValueTag(attr) == IPP_TAG_TEXT) {
254 device_info = ippGetString(attr, 0, NULL);
255 } else if (!strcmp(ippGetName(attr), "device-make-and-model") && ippGetValueTag(attr) == IPP_TAG_TEXT) {
256 device_make_and_model = ippGetString(attr, 0, NULL);
257 } else if (!strcmp(ippGetName(attr), "device-uri") && ippGetValueTag(attr) == IPP_TAG_URI) {
258 device_uri = ippGetString(attr, 0, NULL);
263 if (device_info == NULL || device_make_and_model == NULL
264 || device_uri == NULL) {
266 } else if (strcasestr(device_uri, "usb://") ||
267 strstr(device_uri,"_pdl-datastream.") ||
268 strstr(device_uri,"_ipp.") ||
269 strstr(device_uri,"_printer.")) {
270 pt_printer_info_t *localdetail = NULL;
271 localdetail = pt_util_make_printer_info(device_info, device_make_and_model, device_uri);
272 pt_util_add_printer_to_hashlist(printer_hashlist, localdetail);
274 PT_DEBUG("the device has another scheme such as socket");
279 device_make_and_model = NULL;
283 pt_util_append_printer(search_data, printer_hashlist);
284 g_hash_table_destroy(printer_hashlist);
287 search_data->user_cb(&search_data->response_data);
289 PRINT_SERVICE_FUNC_LEAVE;
292 static void searching_thread_end_cb(void *data, Ecore_Thread *thread)
294 PRINT_SERVICE_FUNC_ENTER;
295 g_pt_info->searching_state = PT_SEARCH_END;
296 PT_DEBUG("Thread is completed successfully.");
297 PRINT_SERVICE_FUNC_LEAVE;
300 static void searching_thread_cancel_cb(void *data, Ecore_Thread *thread)
302 PRINT_SERVICE_FUNC_ENTER;
303 PT_DEBUG("Thread is canceled successfully.");
304 PRINT_SERVICE_FUNC_LEAVE;
307 static void searching_thread(void *data, Ecore_Thread *thread)
309 PRINT_SERVICE_FUNC_ENTER;
310 PT_RET_IF(data == NULL, "data is NULL");
311 PT_RET_IF(thread == NULL, "thread is NULL");
314 ipp_t *request = NULL;
315 ipp_t *response = NULL;
316 int connection_status = 0;
318 char *exclude_schemes[] = {
333 http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
334 PT_RET_IF(http == NULL, "unable to connect server");
336 request = ippNewRequest(CUPS_GET_DEVICES);
337 PT_RET_IF(request == NULL, "unable to create request");
339 ret = pt_get_connection_status(&connection_status);
341 if (ret != PT_ERR_NONE) {
343 PT_DEBUG("unable to get connection status");
346 if ((connection_status & PT_CONNECTION_USB) == 0) {
347 exclude_schemes[num_schemes++] = "usb";
349 if ((connection_status & PT_CONNECTION_WIFI) == 0 &&
350 (connection_status & PT_CONNECTION_WIFI_DIRECT) == 0) {
351 exclude_schemes[num_schemes++] = "dnssd";
354 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "exclude-schemes",
355 num_schemes ,NULL, exclude_schemes);
356 ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "timeout",5);
358 if ((response = cupsDoRequest(http, request, "/")) != NULL) {
359 PT_DEBUG("CUPS_GET_DEVICES (%s)",cupsLastErrorString());
360 if (g_pt_info->searching_state == PT_SEARCH_CANCEL) {
365 if (ecore_thread_feedback(thread, (const void *)response) == EINA_FALSE) {
366 PT_DEBUG("Failed to send data to main loop");
370 PT_DEBUG("CUPS_GET_DEVICES (%s)", cupsLastErrorString());
374 PRINT_SERVICE_FUNC_LEAVE;
377 static void __pt_get_printers(pt_search_data_t *data)
379 PRINT_SERVICE_FUNC_ENTER;
381 g_pt_info->searching_thd_hdl = ecore_thread_feedback_run(
383 searching_thread_notify_cb,
384 searching_thread_end_cb,
385 searching_thread_cancel_cb,
389 PRINT_SERVICE_FUNC_LEAVE;
392 static Eina_Bool __pt_check_cups_before_searching(void *data)
394 PRINT_SERVICE_FUNC_ENTER;
395 Eina_Bool ret = ECORE_CALLBACK_RENEW;
397 if (g_pt_info->cups_pid > 0) {
398 pt_search_data_t *ad = (pt_search_data_t *)data;
399 __pt_get_printers(ad);
400 ret = ECORE_CALLBACK_CANCEL;
403 PRINT_SERVICE_FUNC_LEAVE;
408 * '__enable_printer()' - Enable a printer...
409 * I - Server connection
410 * I - Printer to enable
411 * O - 0 on success, 1 on fail
414 static int __enable_printer(http_t *http, char *printer, char *device_uri)
418 ipp_t *response; /* IPP Response */
419 char uri[HTTP_MAX_URI]; /* URI for printer/class */
422 * Build a CUPS_ADD_PRINTER request, which requires the following
426 * attributes-natural-language
429 * printer-is-accepting-jobs
432 //request = ippNewRequest(CUPS_ADD_PRINTER);
433 request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);
435 //httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", printer);
436 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 631, "/printers/%s", printer);
437 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
439 if (device_uri[0] == '/') {
440 snprintf(uri, sizeof(uri), "file://%s", device_uri);
441 ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL, uri);
443 ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL, device_uri);
446 ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", IPP_PRINTER_IDLE);
448 ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1);
451 * Do the request and get back a response...
453 if ((response = cupsDoRequest(http, request, "/admin/")) == NULL) {
454 PT_DEBUG("cupsDoRequest Failed");
456 } else if (ippGetStatusCode(response) > IPP_OK_EVENTS_COMPLETE) {
457 PT_DEBUG("%x greater than IPP_OK_EVENTS_COMPLETE -- Failed", ippGetStatusCode(response));
467 static int __set_printer_ppd(http_t *http, char *printer, char *ppd_file)
469 ipp_t *request = NULL;
470 ipp_t *response = NULL;
471 char uri[HTTP_MAX_URI] = {0,};
473 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", printer);
475 request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);
477 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
478 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser());
485 if (ppd_file != NULL) {
486 PT_DEBUG("ppd file is not NULL. %s", ppd_file);
488 response = cupsDoFileRequest(http, request, "/admin/", ppd_file);
490 if (response != NULL) {
492 ppd = ppdOpenFile(ppd_file);
494 pt_parse_options(ppd);
497 PT_DEBUG("Failed to call cupsDoFileRequest");
500 PT_DEBUG("ppd file is NULL");
505 if (cupsLastError() > IPP_OK_CONFLICT) {
506 PT_DEBUG("The request is failed, detail description: %s\n", cupsLastErrorString());
514 * This function let the app register the printer to the server
515 * @return If success, return PT_ERR_NONE, else return PT_ERR_FAIL
516 * @param[in] printer_name the pointer to the printer's name
517 * @param[in] scheme the pointer to the register's scheme
518 * @param[in] ip_address the pointer to the printer's address
519 * @param[in] ppd_file the pointer to the printer's ppd file
521 static int pt_utils_regist_printer(char *printer_name, char *scheme, char *ip_address, char *ppd_file)
523 PT_RETV_IF(printer_name == NULL || ip_address == NULL || ppd_file == NULL , 1 , "Invalid argument");
525 /* Connection to server */
527 char device_url[PT_MAX_LENGTH] = {0,};
529 snprintf(device_url, MAX_URI_SIZE, "%s://%s", scheme, ip_address);
531 http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
532 PT_RETV_IF(http == NULL, 1, "Unable to connect to server");
534 if (__enable_printer(http, printer_name, device_url)) {
535 PT_DEBUG("enable return 1");
539 if (__set_printer_ppd(http, printer_name, ppd_file)) {
546 PT_DEBUG("add printer success");
551 * This API let the app get the printer list
552 * @return If success, return PT_ERR_NONE, else return the other error code as defined in pt_err_t
553 * @param[in] callback the pointer to the function which will be excuted after search
554 * @param[in] userdata the pointer to the user data
556 int pt_get_printers(get_printers_cb callback, void *userdata)
558 PRINT_SERVICE_FUNC_ENTER;
559 PT_RETV_IF(g_pt_info == NULL || g_pt_info->search == NULL, PT_ERR_INVALID_PARAM, "Invalid argument");
560 PT_RETV_IF(callback == NULL || userdata == NULL, PT_ERR_INVALID_PARAM, "Invalid argument");
562 /*check the current connection*/
564 int connect_type = 0;
565 status = pt_get_connection_status(&connect_type);
566 PT_RETV_IF(status != PT_ERR_NONE, PT_ERR_FAIL, "Vconf access error");
567 PT_RETV_IF(connect_type == 0, PT_ERR_FAIL, "No available connection");
569 pt_search_data_t *ad = g_pt_info->search;
570 ad->response_data.userdata = userdata;
571 ad->user_cb = callback;
573 PT_RETV_IF(ad->is_searching == 1 , PT_ERR_UNKNOWN, "in searching");
575 /*clear previous search result*/
576 if (ad->pt_local_list != NULL) {
577 pt_utils_free_local_printer_list(ad->pt_local_list);
578 ad->pt_local_list = NULL;
581 /*clear previous search result*/
582 if (ad->response_data.printerlist != NULL) {
583 pt_utils_free_search_list(ad->response_data.printerlist);
584 ad->response_data.printerlist = NULL;
587 g_pt_info->searching_state = PT_SEARCH_IN_PROGRESS;
588 if (g_pt_info->cups_pid > 0) {
589 __pt_get_printers(ad);
591 g_pt_info->cups_checking_timer = ecore_timer_add(1.0, (Ecore_Task_Cb)__pt_check_cups_before_searching, ad);
594 PRINT_SERVICE_FUNC_LEAVE;
599 * This API let the app cancel getting the printer list
600 * @return If success, return PT_ERR_NONE, else return the other error code as defined in pt_err_t
602 int pt_cancel_get_printers()
604 PRINT_SERVICE_FUNC_ENTER;
605 PT_RETV_IF(g_pt_info == NULL, PT_ERR_INVALID_PARAM, "g_pt_info is NULL");
606 PT_RETV_IF(g_pt_info->search == NULL, PT_ERR_INVALID_PARAM, "g_pt_info->search is NULL");
607 PT_RETV_IF(g_pt_info->searching_thd_hdl == NULL, PT_ERR_INVALID_PARAM, "g_pt_info->searching_thd_hdl is NULL");
609 pt_search_data_t *ad = g_pt_info->search;
611 if (g_pt_info->cups_checking_timer) {
612 ecore_timer_del(g_pt_info->cups_checking_timer);
613 g_pt_info->cups_checking_timer = NULL;
616 if (ecore_thread_cancel(g_pt_info->searching_thd_hdl) == EINA_FALSE) {
617 PT_DEBUG("Canceling of searching_thd_hdl[%p] is pended", g_pt_info->searching_thd_hdl);
620 g_pt_info->searching_state = PT_SEARCH_CANCEL;
622 /*clear the search result*/
623 if (ad->pt_local_list != NULL) {
624 pt_utils_free_local_printer_list(ad->pt_local_list);
625 ad->pt_local_list = NULL;
628 /*clear the search result*/
629 if (ad->response_data.printerlist != NULL) {
630 pt_utils_free_search_list(ad->response_data.printerlist);
631 ad->response_data.printerlist = NULL;
634 ad->response_data.userdata = NULL;
637 PRINT_SERVICE_FUNC_LEAVE;
642 * This API let the app get the current default printer
643 * allocates memory for printer info structure! Please free after use!
644 * @return If success, return PT_ERR_NONE, else return the other error code as defined in pt_err_t
645 * @param[out] printer the pointer to the printer object
647 int pt_get_default_printer(pt_printer_mgr_t **printer)
649 PRINT_SERVICE_FUNC_ENTER;
650 PT_RETV_IF(printer == NULL || g_pt_info == NULL, PT_ERR_INVALID_PARAM, "Invalid argument");
651 pt_printer_mgr_t *pt = NULL;
653 /* check whether if the default printer exists in the preference */
656 ret = preference_is_existing(PREFERENCE_DEFAULT_PRINTER_NAME, &isexist);
657 PT_RETV_IF(!isexist, PT_ERR_FAIL, "the default printer name isn't exist in preference!");
659 ret = preference_is_existing(PREFERENCE_DEFAULT_PRINTER_ADDRESS, &isexist);
660 PT_RETV_IF(!isexist, PT_ERR_FAIL, "the default printer name isn't exist in preference!");
662 /* get the printer in the preference */
664 ret = preference_get_string(PREFERENCE_DEFAULT_PRINTER_NAME, &name);
665 PT_RETV_IF(ret, PT_ERR_FAIL, "get the default printer name failed, errno: %d!", ret);
667 char *address = NULL;
668 ret = preference_get_string(PREFERENCE_DEFAULT_PRINTER_ADDRESS, &address);
669 PT_RETV_IF(ret, PT_ERR_FAIL, "get the default printer name failed, errno: %d!", ret);
671 pt = (pt_printer_mgr_t *)calloc(1, sizeof(pt_printer_mgr_t));
672 PT_RETV_IF(pt == NULL, PT_ERR_FAIL, "Failed to calloc pt");
673 memcpy(pt->name, name, PT_MAX_LENGTH);
674 memcpy(pt->address, address, PT_MAX_LENGTH);
676 memcpy(g_pt_info->active_printer, pt, sizeof(pt_printer_mgr_t));
678 PT_DEBUG("get printer info from preference, name: %s, address: %s!",
679 pt->name, pt->address);
681 PT_IF_FREE_MEM(name);
682 PT_IF_FREE_MEM(address);
686 PRINT_SERVICE_FUNC_LEAVE;
691 * This API let the app set a printer as the default printer
692 * @return If success, return PT_ERR_NONE, else return the other error code as defined in pt_err_t
693 * @param[in] printer the pointer to the printer object
695 int pt_set_default_printer(pt_printer_mgr_t *printer)
697 PRINT_SERVICE_FUNC_ENTER;
698 PT_RETV_IF(printer == NULL || g_pt_info == NULL, PT_ERR_INVALID_PARAM, "Invalid argument");
700 /*check the current connection*/
702 int connect_type = 0;
703 status = pt_get_connection_status(&connect_type);
705 PT_RETV_IF(status != PT_ERR_NONE, PT_ERR_FAIL, "Vconf access error");
706 PT_RETV_IF(connect_type == 0, PT_ERR_FAIL, "No available connection");
708 /* set the printer name in the preference */
710 ret = preference_set_string(PREFERENCE_DEFAULT_PRINTER_NAME, (const char *)printer->name);
711 PT_RETV_IF(ret, PT_ERR_FAIL, "set the default printer name(%s) failed!", printer->name);
713 /* set the printer address in the preference */
714 ret = preference_set_string(PREFERENCE_DEFAULT_PRINTER_ADDRESS, (const char *)printer->address);
715 PT_RETV_IF(ret, PT_ERR_FAIL, "set the default printer name(%s) failed!", printer->address);
717 /* set the printer address in the preference */
718 ret = preference_set_string(PREFERENCE_DEFAULT_PRINTER_MFG, (const char *)printer->mfg);
719 PT_RETV_IF(ret, PT_ERR_FAIL, "set the default printer name(%s) failed!", printer->mfg);
721 /* set the printer address in the preference */
722 ret = preference_set_string(PREFERENCE_DEFAULT_PRINTER_MDL, (const char *)printer->mdl);
723 PT_RETV_IF(ret, PT_ERR_FAIL, "set the default printer name(%s) failed!", printer->mdl);
725 PRINT_SERVICE_FUNC_LEAVE;
730 * This API let the app get the current active printer
731 * allocates memory for printer info structure! Please free after use!
732 * @return If success, return PT_ERR_NONE, else return the other error code as defined in pt_err_t
733 * @param[out] printer the pointer to the printer object
735 int pt_get_active_printer(pt_printer_mgr_t **printer)
737 PRINT_SERVICE_FUNC_ENTER;
738 PT_RETV_IF(g_pt_info == NULL || g_pt_info->active_printer == NULL
739 , PT_ERR_INVALID_PARAM, "global printer information is NULL or no active printer");
740 PT_RETV_IF(printer == NULL, PT_ERR_INVALID_PARAM, "printer is NULL");
742 pt_printer_mgr_t *pt = NULL;
743 pt = (pt_printer_mgr_t *)malloc(sizeof(pt_printer_mgr_t));
744 PT_RETV_IF(pt == NULL, PT_ERR_NO_MEMORY, "Not enough memory");
746 memset(pt, 0, sizeof(pt_printer_mgr_t));
747 memcpy(pt, g_pt_info->active_printer, sizeof(pt_printer_mgr_t));
749 PT_DEBUG("g_pt_info->active_printer->name %s" , g_pt_info->active_printer->name);
750 PT_DEBUG("g_pt_info->active_printer->actived = %d", g_pt_info->active_printer->actived);
751 PT_DEBUG("g_pt_info->active_printer->ppd%s" , g_pt_info->active_printer->ppd);
752 PT_DEBUG("g_pt_info->active_printer->address %s" , g_pt_info->active_printer->address);
753 PT_DEBUG("g_pt_info->active_printer->mfg %s" , g_pt_info->active_printer->mfg);
754 PT_DEBUG("g_pt_info->active_printer->mdl %s" , g_pt_info->active_printer->mdl);
758 PRINT_SERVICE_FUNC_LEAVE;
764 * This API let the app select a specify printer as active printer
765 * @return If success, return PT_ERR_NONE, else return the other error code as defined in pt_err_t
766 * @param[in] printer the pointer to the printer object
768 int pt_set_active_printer(pt_printer_mgr_t *printer)
770 PRINT_SERVICE_FUNC_ENTER;
771 PT_RETV_IF(g_pt_info == NULL || g_pt_info->active_printer == NULL
772 , PT_ERR_INVALID_PARAM, "global printer information is NULL or no active printer");
773 PT_RETV_IF(printer == NULL, PT_ERR_INVALID_PARAM, "printer is NULL");
775 /*check the current connection*/
777 int connect_type = 0;
778 status = pt_get_connection_status(&connect_type);
780 PT_RETV_IF(status != PT_ERR_NONE, PT_ERR_FAIL, "Vconf access error");
781 PT_RETV_IF(connect_type == 0, PT_ERR_FAIL, "No available connection");
783 /*register the printer*/
786 if (pt_get_printer_ppd(printer) != PT_ERR_NONE) {
787 /* Error can not get ppd info*/
788 PT_DEBUG("Get %s ppd failed", printer->name);
789 return PT_ERR_INVALID_PARAM;
792 PT_DEBUG("Get ppd info: %s", printer->ppd);
793 PT_DEBUG("address is %s", printer->address);
795 if ((strncasecmp(printer->address, "usb://", 6) == 0)) {
797 char *address = printer->address + sizeof("usb://") - 1;
798 PT_DEBUG("usb address: %s", address);
801 ret = pt_utils_regist_printer(printer->name, "usb", address, printer->ppd);
803 } else if ((strncasecmp(printer->address, "dnssd://", 8) == 0)) {
805 char *address = printer->address + sizeof("dnssd://") - 1;
806 PT_DEBUG("dnssd address: %s", address);
809 PT_DEBUG("1. printer structure address: %x", printer);
810 ret = pt_utils_regist_printer(printer->name, "dnssd", address, printer->ppd);
811 PT_DEBUG("2. printer structure address: %x", printer);
814 ret = pt_utils_regist_printer(printer->name, "socket", printer->address, printer->ppd);
817 PT_RETV_IF(ret != PT_ERR_NONE, PT_ERR_UNKNOWN, "add printer failed, description:%s", cupsLastErrorString());
819 /* only actived printer can print file */
820 printer->actived = 1;
821 memcpy(g_pt_info->active_printer, printer, sizeof(pt_printer_mgr_t));
822 PT_DEBUG("g_pt_info->active_printer->name %s" , g_pt_info->active_printer->name);
823 PT_DEBUG("g_pt_info->active_printer->address %s" , g_pt_info->active_printer->address);
824 PT_DEBUG("g_pt_info->active_printer->mfg %s" , g_pt_info->active_printer->mfg);
825 PT_DEBUG("g_pt_info->active_printer->mdl %s" , g_pt_info->active_printer->mdl);
827 PRINT_SERVICE_FUNC_LEAVE;