43 #define MAX_IP_CONNECTIONS 10 44 #define IP_TASK_STACK_SIZE 4096 45 #define IP_TASK_PRIORITY 9 46 #define IP_RECV_BUFFER_SIZE 65536 47 #define IP_RECV_TIMEOUT 500 61 U8BIT *recv_buffer[2];
62 S32BIT recv_num_bytes[2];
65 BOOLEAN recv_buffer_sent;
71 static void *ip_mutex = NULL;
87 FUNCTION_START(FindIPConnection);
89 for (index = 0; index < MAX_IP_CONNECTIONS; index++)
91 if (ip_connections[index].module == module)
93 ipc = &ip_connections[index];
98 FUNCTION_FINISH(FindIPConnection);
107 static void IPSendDataTask(
void *param)
113 FUNCTION_START(IPSendDataTask);
122 if (ipc->socket != NULL)
124 bufptr = ipc->send_buffer;
128 if ((bytes_sent =
STB_NWSend(ipc->socket, bufptr, ipc->send_length)) >= 0)
130 if (ipc->send_length >= bytes_sent)
132 bufptr += bytes_sent;
133 ipc->send_length -= bytes_sent;
137 DBGPRINT(
" Sending %u bytes, but sent %ld for module 0x%08x",
138 ipc->send_length, bytes_sent, ipc->module)
140 ipc->send_length = 0;
146 DBGPRINT(
" Failed to send data for module 0x%08x", ipc->module)
150 while ((bytes_sent >= 0) && (ipc->send_length > 0));
154 DBGPRINT(
" Data sent for module 0x%08lx", ipc->module)
156 STB_CINotifyIPStatus(ipc->module, STB_CI_IP_STATUS_DATA_SENT);
161 FUNCTION_FINISH(IPSendDataTask);
174 FUNCTION_START(IPReadData);
179 bytes_free = IP_RECV_BUFFER_SIZE - ipc->recv_num_bytes[ipc->fill_index];
182 bufptr = ipc->recv_buffer[ipc->fill_index] + ipc->recv_num_bytes[ipc->fill_index];
186 DBGPRINT(
"(0x%08lx): read %ld bytes into buffer %u", ipc->module, bytes_read, ipc->fill_index)
188 ipc->recv_num_bytes[ipc->fill_index] += bytes_read;
191 if (!ipc->recv_buffer_sent)
193 DBGPRINT(
"(0x%08lx): Buffer %u ready, sending", ipc->module, ipc->fill_index)
196 ipc->send_index = ipc->fill_index;
197 ipc->fill_index = (ipc->fill_index + 1) % 2;
199 if (STB_CIHandleIPData(ipc->module, ipc->recv_buffer[ipc->send_index],
200 ipc->recv_num_bytes[ipc->send_index]))
202 ipc->recv_buffer_sent = TRUE;
206 DBGPRINT(
": STB_CIHandleIPData failed for module 0x%08lx", ipc->module)
209 ipc->recv_num_bytes[ipc->send_index] = 0;
215 DBGPRINT(
"(0x%08lx): Buffer %u ready but can't send", ipc->module, ipc->fill_index)
222 DBGPRINT(
"(0x%08lx): Read failed, closing the connection", ipc->module)
223 STB_CICloseIPConnection(ipc->module);
229 FUNCTION_FINISH(IPReadData);
236 static void IPReceiveDataTask(
void *param)
243 FUNCTION_START(IPReceiveDataTask);
244 USE_UNWANTED_PARAM(param);
254 for (i = 0; i < MAX_IP_CONNECTIONS; i++)
256 if (ip_connections[i].socket != NULL)
268 if (
STB_NWSelect(&read_sockets, NULL, &except_sockets, IP_RECV_TIMEOUT) > 0)
273 for (i = 0; i < MAX_IP_CONNECTIONS; i++)
275 if (ip_connections[i].socket != NULL)
286 IPReadData(&ip_connections[i]);
301 FUNCTION_FINISH(IPReceiveDataTask);
305 static void PrintIPAddress(S_STB_CI_IP_ADDR *addr)
307 FUNCTION_START(PrintIPAddress);
311 case STB_CI_IP_ADDR_V4:
312 PRINTDBG(
"%u.%u.%u.%u", addr->data.ipv4_addr[0], addr->data.ipv4_addr[1], addr->data.ipv4_addr[2],
313 addr->data.ipv4_addr[3])
316 case STB_CI_IP_ADDR_V6:
317 PRINTDBG(
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
318 addr->data.ipv6_addr[0], addr->data.ipv6_addr[1], addr->data.ipv6_addr[2],
319 addr->data.ipv6_addr[3], addr->data.ipv6_addr[4], addr->data.ipv6_addr[5],
320 addr->data.ipv6_addr[6], addr->data.ipv6_addr[7], addr->data.ipv6_addr[8],
321 addr->data.ipv6_addr[9], addr->data.ipv6_addr[10], addr->data.ipv6_addr[11],
322 addr->data.ipv6_addr[12], addr->data.ipv6_addr[13], addr->data.ipv6_addr[14],
323 addr->data.ipv6_addr[15])
326 case STB_CI_IP_ADDR_HOSTNAME:
327 PRINTDBG(
"\"%s\"", addr->data.hostname)
331 FUNCTION_FINISH(PrintIPAddress);
339 void CIP_GlueNetInitialise(
void)
344 if (ip_mutex != NULL)
346 for (i = 0; i != MAX_IP_CONNECTIONS; i++)
348 ip_connections[i].socket = NULL;
354 STB_OSCreateTask(IPSendDataTask, &ip_connections[i], IP_TASK_STACK_SIZE, IP_TASK_PRIORITY, (U8BIT *)
"IPSendData");
360 STB_OSCreateTask(IPReceiveDataTask, NULL, IP_TASK_STACK_SIZE, IP_TASK_PRIORITY, (U8BIT *)
"IPReceiveData");
379 U16BIT STB_CIGetMaxIPConnections(
void)
381 FUNCTION_START(STB_CIGetMaxIPConnections);
382 FUNCTION_FINISH(STB_CIGetMaxIPConnections);
384 return MAX_IP_CONNECTIONS;
414 void STB_CIOpenIPConnection(U32BIT module, S_STB_CI_IP_ADDR *addr,
415 U16BIT port, E_STB_CI_IP_PROTOCOL protocol,
418 BOOLEAN connected = FALSE;
420 E_NW_PROTOCOL nw_protocol;
429 FUNCTION_START(STB_CIOpenIPConnection);
430 USE_UNWANTED_PARAM(timeout);
432 if (ip_mutex == NULL)
434 CIP_GlueNetInitialise();
437 for (index = 0; index < MAX_IP_CONNECTIONS; index++)
439 if (ip_connections[index].socket == NULL)
441 if (protocol == STB_CI_IP_PROTOCOL_TCP)
443 nw_protocol = NW_PROTOCOL_TCP;
447 nw_protocol = NW_PROTOCOL_UDP;
454 case STB_CI_IP_ADDR_V4:
455 af_type = NW_AF_INET;
456 sprintf((
char *)address,
"%u.%u.%u.%u", addr->data.ipv4_addr[0], addr->data.ipv4_addr[1],
457 addr->data.ipv4_addr[2], addr->data.ipv4_addr[3]);
460 case STB_CI_IP_ADDR_HOSTNAME:
465 for (i = 0; (i < num_addrs) && !valid; i++)
467 if (nw_addrs[i].type == NW_SOCK_STREAM)
470 af_type = nw_addrs[i].af;
471 nw_protocol = nw_addrs[i].protocol;
472 strcpy((
char *)address, (
char *)nw_addrs[i].addr);
485 case STB_CI_IP_ADDR_V6:
486 af_type = NW_AF_INET6;
487 sprintf((
char *)address,
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
488 addr->data.ipv6_addr[0], addr->data.ipv6_addr[1], addr->data.ipv6_addr[2],
489 addr->data.ipv6_addr[3], addr->data.ipv6_addr[4], addr->data.ipv6_addr[5],
490 addr->data.ipv6_addr[6], addr->data.ipv6_addr[7], addr->data.ipv6_addr[8],
491 addr->data.ipv6_addr[9], addr->data.ipv6_addr[10], addr->data.ipv6_addr[11],
492 addr->data.ipv6_addr[12], addr->data.ipv6_addr[13], addr->data.ipv6_addr[14],
493 addr->data.ipv6_addr[15]);
503 if ((socket =
STB_NWOpenSocket(af_type, NW_SOCK_STREAM, nw_protocol, FALSE)) != NULL)
510 ip_connections[index].socket = socket;
511 ip_connections[index].module = module;
516 for (i = 0; i < 2; i++)
518 ip_connections[index].recv_num_bytes[i] = 0;
519 ip_connections[index].recv_buffer[i] =
STB_MEMGetSysRAM(IP_RECV_BUFFER_SIZE);
520 if (ip_connections[index].recv_buffer[i] == NULL)
522 DBGPRINT(
"(0x%08x): Failed to allocate memory for receive buffer", module)
526 ip_connections[index].fill_index = 0;
527 ip_connections[index].send_index = 0;
528 ip_connections[index].recv_buffer_sent = FALSE;
534 DBGPRINT(
"(0x%08x): Successfully connected to \"%s\", port %u",
535 module, address, port)
537 STB_CINotifyIPStatus(module, STB_CI_IP_STATUS_CONNECTED);
546 DBGPRINT(
"(0x%08x): Failed to connect to \"%s\", port %u",
547 module, address, port)
553 DBGPRINT(
"(0x%08x): Failed to open socket", module)
563 if (index >= MAX_IP_CONNECTIONS)
565 DBGPRINT(
"(0x%08x): No more connections available to connect to ", module)
566 PrintIPAddress(addr);
570 STB_CINotifyIPStatus(module, STB_CI_IP_STATUS_DISCONNECTED);
573 FUNCTION_FINISH(STB_CIOpenIPConnection);
602 void STB_CISendIPData(U32BIT module, U8BIT *buffer, U16BIT len)
606 FUNCTION_START(STB_CISendIPData);
608 if ((ipc = FindIPConnection(module)) != NULL)
610 if (ipc->socket != NULL)
612 DBGPRINT(
"(0x%08x): len=%u", module, len)
616 ipc->send_buffer = buffer;
617 ipc->send_length = len;
623 FUNCTION_FINISH(STB_CISendIPData);
642 void STB_CIReleaseIPData(U32BIT module, U8BIT *buffer)
646 FUNCTION_START(STB_CIReleaseIPData);
647 USE_UNWANTED_PARAM(buffer);
649 if ((ipc = FindIPConnection(module)) != NULL)
654 if (ipc->recv_buffer[ipc->send_index] != buffer)
656 DBGPRINT(
"(0x%08lx): Expected buffer %u(%p) but received buffer %p", module,
657 ipc->send_index, ipc->recv_buffer[ipc->send_index], buffer)
661 DBGPRINT(
"(0x%08lx): Buffer %u", module, ipc->send_index)
665 ipc->recv_buffer_sent = FALSE;
666 ipc->recv_num_bytes[ipc->send_index] = 0;
669 ipc->send_index = (ipc->send_index + 1) % 2;
671 if (ipc->recv_num_bytes[ipc->send_index] > 0)
673 DBGPRINT(
"(0x%08lx): Sending buffer %u", module, ipc->send_index)
675 if (STB_CIHandleIPData(ipc->module, ipc->recv_buffer[ipc->send_index],
676 ipc->recv_num_bytes[ipc->send_index]))
678 ipc->recv_buffer_sent = TRUE;
681 if (ipc->fill_index == ipc->send_index)
684 ipc->fill_index = (ipc->fill_index + 1) % 2;
689 DBGPRINT(
"(0x%08lx): STB_CIHandleIPData failed", module)
692 ipc->recv_num_bytes[ipc->send_index] = 0;
699 FUNCTION_FINISH(STB_CIReleaseIPData);
714 void STB_CICloseIPConnection(U32BIT module)
719 FUNCTION_START(STB_CICloseIPConnection);
723 if ((ipc = FindIPConnection(module)) != NULL)
725 if (ipc->socket != NULL)
731 DBGPRINT(
"(0x%08x) STB_NWCloseSocket failed", module)
738 for (i = 0; i < 2; i++)
740 if (ipc->recv_buffer[i] != NULL)
743 ipc->recv_buffer[i] = NULL;
751 STB_CINotifyIPStatus(module, STB_CI_IP_STATUS_DISCONNECTED);
755 FUNCTION_FINISH(STB_CICloseIPConnection);
771 USE_UNWANTED_PARAM(comms_ip_config);
790 COMMS_IP_CONFIG_IP_ARRAY_T *DNS_server_to_populate)
793 USE_UNWANTED_PARAM(index);
794 USE_UNWANTED_PARAM(DNS_server_to_populate);
818 S_STB_CI_MULTICAST_DESCRIPTOR *descriptor,
822 USE_UNWANTED_PARAM(module);
823 USE_UNWANTED_PARAM(descriptor);
824 USE_UNWANTED_PARAM(timeout);
BOOLEAN STB_NWCloseSocket(void *socket)
Closes (destroys) a socket instance.
U16BIT STB_NWLookupAddress(U8BIT *name, S_NW_ADDR_INFO **nw_addrs)
Performs a lookup to find the IP address(es) of the given host name.
void * STB_NWOpenSocket(E_NW_AF af, E_NW_TYPE type, E_NW_PROTOCOL protocol, BOOLEAN nonblock)
Opens (creates) a new socket for subsequent use.
void * STB_OSCreateSemaphore(void)
Create a Semaphore.
void STB_OSSemaphoreSignal(void *semaphore)
Signal a Semaphore to Release it by decrementing its counter.
E_NW_ERROR STB_NWConnect(void *socket, U8BIT *address, U32BIT port)
Connects the socket to a remote host.
void STB_OSMutexUnlock(void *mutex)
Unlock a mutex (a.k.a. 'leave', 'signal' or 'release')
void STB_OSSemaphoreWait(void *semaphore)
Wait on Semaphore Indefinity or Until Released.
BOOLEAN STB_CIOpenMulticastConnection(U32BIT module, S_STB_CI_MULTICAST_DESCRIPTOR *descriptor, U8BIT timeout)
This function is called by the CI+ stack to open an multicast IP connection. If multicast is not supp...
BOOLEAN STB_NWSockIsSet(void *socket, S_NW_SOCKSET *socks)
Returns whether a specified socket is a member of a specified set.
void STB_CIGetCommsIPConfig(S_STB_CI_COMMS_IP_CONFIG *comms_ip_config)
This function is called by the CI+ stack to find out the IP configuration information from the Host...
void * STB_MEMGetSysRAM(U32BIT bytes)
Allocates a new block of memory for system use.
Debug functions header file.
void STB_OSMutexLock(void *mutex)
Lock a mutex (a.k.a. 'enter', 'wait' or 'get').
void STB_MEMFreeSysRAM(void *block)
Releases a previously allocated block of system memory.
S32BIT STB_NWSelect(S_NW_SOCKSET *read_sockets, S_NW_SOCKSET *write_sockets, S_NW_SOCKSET *except_sockets, S32BIT timeout_ms)
Determines the status of one or more sockets, blocking if necessary.
Header file - Function prototypes for NVM and Heap.
Header file - Function prototypes for operating system.
S32BIT STB_NWReceive(void *socket, U8BIT *buf, U32BIT max_bytes)
Receives data from a connected socket.
System Wide Global Technical Data Type Definitions.
S32BIT STB_NWSend(void *socket, U8BIT *buf, U32BIT num_bytes)
Sends data on a connected socket.
BOOLEAN STB_CIGetCommsIPConfigDNSServersAtIndex(U8BIT index, COMMS_IP_CONFIG_IP_ARRAY_T *DNS_server_to_populate)
This function is called by the CI+ stack to find out the IP address of a configured DNS server...
void * STB_OSCreateTask(void(*function)(void *), void *param, U32BIT stack, U8BIT priority, U8BIT *name)
Create a New Task to the calling process. Upon success, the created task runs on its own stack...
void STB_NWSockSet(void *socket, S_NW_SOCKSET *socks)
Sets a specificed socket in a specified set.
void * STB_OSCreateMutex(void)
Create a mutex.
void STB_NWSockZero(S_NW_SOCKSET *socks)
Clears the socket set.
void STB_OSTaskDelay(U16BIT timeout)
Delay Task for Specifed Time Period.