реклама на сайте
подробности

 
 
> rawprint lwip
РљРѕС‚-Р...
сообщение May 14 2013, 07:39
Сообщение #1





Группа: Новичок
Сообщений: 3
Регистрация: 3-05-06
Пользователь №: 16 735



Имеется следующая железка: интерфейсная плата принтера на Cortex-M3 + lwip.
Поверх lwip реализован простой raw-print сервер, который слушает порт 9100 и отсылает принятые
данные в принтер. Все работает хорошо до тех пор, пока в одно и то же время не поступают две и
более задач с планировщиков печати (спулеров) разных хостов. Суть вопроса: необходимо средствами
lwip разграничить доступ к принтеру, то есть обеспечить режим "занят" в момент обработки текущей задачи.

На данный момент есть эксперементальный код, который, собственно практически не работает...
Идея в том чтобы запомнить ip для текущей задачи (rawprint_remote_ip) и пока соединение не будет закрыто отправлять
все новые задачи через tcp_poll в ожидание.
Инициализация:
Код
void
rawprintd_init(void)
{
  struct tcp_pcb *pcb;

  LWIP_DEBUGF(RAW_PRINTD_DEBUG, ("rawprintd_init\n"));

  pcb = tcp_new();
  tcp_bind(pcb, IP_ADDR_ANY, 9100);
  pcb = tcp_listen(pcb);
  tcp_accept(pcb, rawprint_accept);

}

Подтвержение:
CODE
static err_t
rawprint_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
struct rawprint_state *rs;

LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(err);

LWIP_DEBUGF(RAW_PRINTD_DEBUG, ("rawprint_accept 0x%08x\n", pcb));

/* Allocate memory for the structure that holds the state of the
connection. */
rs = (struct rawprint_state *)mem_malloc(sizeof(struct rawprint_state));

if (rs == NULL) {
LWIP_DEBUGF(RAW_PRINTD_DEBUG, ("rawprint_accept: Out of memory\n"));
return ERR_MEM;
}

/* Initialize the structure. */
rs->retries = 0;

/* Tell TCP that this is the structure we wish to be passed for our
callbacks. */
tcp_arg(pcb, rs);

/* Tell TCP that we wish to be informed of incoming data by a call
to the http_recv() function. */
if (pcb->local_port == 9100)
{
if (rawprint_remote_ip == 0)
{
tcp_recv(pcb, rawprint_recv);

tcp_err(pcb, conn_err);

rawprint_remote_ip = pcb->remote_ip.addr;

rawprint_send_status(pcb, false);

LWIP_DEBUGF(RAW_PRINTD_DEBUG, ("rawprint_remote_ip %08x\n", rawprint_remote_ip));
}
else
{
LWIP_DEBUGF(RAW_PRINTD_DEBUG, ("go poll\n"));
tcp_poll(pcb, rawprint_poll, 1);
}
}

return ERR_OK;
}

Прием данных:
CODE
static err_t
rawprint_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
tBoolean bSendStatus = false;
struct rawprint_state *rs;

LWIP_DEBUGF(RAW_PRINTD_DEBUG, ("rawprint_recv 0x%08x port %d\n", pcb, (unsigned int)pcb->local_port));

rs = arg;

if ((err == ERR_OK) && (p != NULL) && rs)
{

/* Inform TCP that we have taken the data. */
tcp_recved(pcb, p->tot_len);

LWIP_DEBUGF(RAW_PRINTD_DEBUG, ("rawprint_recv length %d bytes\n", p->tot_len));

if (p->len)
{
const unsigned char *pucData = p->payload;
switch(pcb->local_port)
{
case 9100:
if (!((pucData[0] == 0x00) && (p->len == 1)))
rawprint_printer_write(p);
if ((memcmp(g_pucReadPort, pucData, sizeof(g_pucReadPort)) == 0) && (p->len == sizeof(g_pucReadPort)))
bSendStatus = true;
break;
}
}
pbuf_free(p);
}

if (((err == ERR_OK) && (p == NULL)) || (bSendStatus))
{
rawprint_send_status(pcb, true);
}

return ERR_OK;
}

Опрос:
CODE
static err_t
rawprint_poll(void *arg, struct tcp_pcb *pcb)
{
struct rawprint_state *rs;

rs = arg;

LWIP_DEBUGF(RAW_PRINTD_DEBUG, ("rawprint_poll 0x%08x port %d\n", pcb, pcb->local_port));

/* printf("Polll\n");*/
if ((rs == NULL) && (pcb->state == ESTABLISHED)) {
/* printf("Null, close\n");*/
tcp_abort(pcb);
return ERR_ABRT;
} else {
if (rawprint_remote_ip == 0)
{
tcp_recv(pcb, rawprint_recv);

tcp_err(pcb, conn_err);

rawprint_remote_ip = pcb->remote_ip.addr;

rawprint_send_status(pcb, false);

LWIP_DEBUGF(RAW_PRINTD_DEBUG, ("rawprint_remote_ip %08x\n", rawprint_remote_ip));
}

}

return ERR_OK;
}

Закрытие соединения:
CODE
/*-----------------------------------------------------------------------------------*/
static void
close_conn(struct tcp_pcb *pcb, struct rawprint_state *rs)
{
err_t err;
LWIP_DEBUGF(RAW_PRINTD_DEBUG, ("Closing connection 0x%08x\n", pcb));

tcp_arg(pcb, NULL);
tcp_sent(pcb, NULL);
tcp_recv(pcb, NULL);
if(rs) {
mem_free(rs);
}

if (pcb->remote_ip.addr == rawprint_remote_ip){
rawprint_remote_ip = 0;
}

err = tcp_close(pcb);
if(err != ERR_OK)
{
LWIP_DEBUGF(RAW_PRINTD_DEBUG, ("Error %d closing 0x%08x\n", err, pcb));
}
}


Я не совсем уверен в правильности вызова функции tcp_poll без tcp_recv в случае, когда задача уже запущена (rawprint_remote_ip != 0).
Есть у кого-нибудь идеи как реализовать правильно без буферизации, если это, конечно возможно?

Сообщение отредактировал IgorKossak - May 14 2013, 07:54
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Golikov A.
сообщение May 15 2013, 07:27
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



почему не работает?
а где рав принт ремоте сбрасывается в 0?
по идее по дисконекту это должно было бы произойти.

а вы учитываете что p - имеет еще поле тотал лен и ссылку на следущий p

вызывая функцию ресивед вы говорите сколько данных из всего окна вы обработали, но те окна что вы пропустили не обработав, могут получить и 2 пакет данных и третий, и перейдя к ним надо бы все данные обработать...
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 20:10
Рейтинг@Mail.ru


Страница сгенерированна за 0.01374 секунд с 7
ELECTRONIX ©2004-2016