DVBCore  20.3.0
DVBCore Documentation
ci_glue_net.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2009 Ocean Blue Software Ltd
4  *
5  * This file is part of a DTVKit Software Component
6  * You are permitted to copy, modify or distribute this file subject to the terms
7  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
8  *
9  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
11  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * If you or your organisation is not a member of DTVKit then you have access
14  * to this source code outside of the terms of the licence agreement
15  * and you are expected to delete this and any associated files immediately.
16  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
17  *******************************************************************************/
24 /*---includes for this file--------------------------------------------------*/
25 
26 /* compiler library header files */
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdarg.h>
30 
31 /* third party header files */
32 
33 /* DVBCore header files */
34 #include "techtype.h"
35 #include "dbgfuncs.h"
36 #include "stbhwos.h"
37 #include "stbci.h"
38 #include "stbhwnet.h"
39 #include "stbhwmem.h"
40 
41 /*---constant definitions for this file--------------------------------------*/
42 
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
48 
49 /*---local typedef enums for this file-------------------------------------*/
50 
51 /*---local typedef structs for this file-------------------------------------*/
52 
53 typedef struct network_connection
54 {
55  U32BIT module;
56  void *send_data_sem;
57  void *socket;
58  U8BIT *send_buffer;
59  S32BIT send_length;
60  void *recv_mutex;
61  U8BIT *recv_buffer[2];
62  S32BIT recv_num_bytes[2];
63  U8BIT fill_index;
64  U8BIT send_index;
65  BOOLEAN recv_buffer_sent;
67 
68 /*---local (static) variable declarations for this file----------------------*/
69 /* (internal variables declared static to make them local) */
70 
71 static void *ip_mutex = NULL;
72 static S_NETWORK_CONNECTION ip_connections[MAX_IP_CONNECTIONS];
73 
74 static void IPReadData(S_NETWORK_CONNECTION *ipc);
75 
76 
77 /*!**************************************************************************
78  * @brief Find IP connection for the given module
79  * @param module - module
80  * @return Pointer to connection information, NULL if not found
81  ****************************************************************************/
82 static S_NETWORK_CONNECTION* FindIPConnection(U32BIT module)
83 {
84  U8BIT index;
85  S_NETWORK_CONNECTION *ipc = NULL;
86 
87  FUNCTION_START(FindIPConnection);
88 
89  for (index = 0; index < MAX_IP_CONNECTIONS; index++)
90  {
91  if (ip_connections[index].module == module)
92  {
93  ipc = &ip_connections[index];
94  break;
95  }
96  }
97 
98  FUNCTION_FINISH(FindIPConnection);
99 
100  return(ipc);
101 }
102 
103 /*!**************************************************************************
104  * @brief Background task that sends data using a given network connection
105  * @param param - S_NETWORK_CONNECTION* to be used
106  ****************************************************************************/
107 static void IPSendDataTask(void *param)
108 {
110  S32BIT bytes_sent;
111  U8BIT *bufptr;
112 
113  FUNCTION_START(IPSendDataTask);
114 
115  if (ipc != NULL)
116  {
117  while (1)
118  {
119  /* Wait for a communication request through the connection */
120  STB_OSSemaphoreWait(ipc->send_data_sem);
121 
122  if (ipc->socket != NULL)
123  {
124  bufptr = ipc->send_buffer;
125 
126  do
127  {
128  if ((bytes_sent = STB_NWSend(ipc->socket, bufptr, ipc->send_length)) >= 0)
129  {
130  if (ipc->send_length >= bytes_sent)
131  {
132  bufptr += bytes_sent;
133  ipc->send_length -= bytes_sent;
134  }
135  else
136  {
137  DBGPRINT(" Sending %u bytes, but sent %ld for module 0x%08x",
138  ipc->send_length, bytes_sent, ipc->module)
139 
140  ipc->send_length = 0;
141  }
142  }
143 #ifdef DEBUG_IP
144  else
145  {
146  DBGPRINT(" Failed to send data for module 0x%08x", ipc->module)
147  }
148 #endif
149  }
150  while ((bytes_sent >= 0) && (ipc->send_length > 0));
151 
152  /* Whether data has been sent or the send failed, inform the CI+ stack that the buffer
153  * is no longer being used */
154  DBGPRINT(" Data sent for module 0x%08lx", ipc->module)
155 
156  STB_CINotifyIPStatus(ipc->module, STB_CI_IP_STATUS_DATA_SENT);
157  }
158  }
159  }
160 
161  FUNCTION_FINISH(IPSendDataTask);
162 }
163 
164 /*!**************************************************************************
165  * @brief Used by IPReceiveDataTask to read data on a socket and pass it to the CI+ stack
166  * @param ipc - network connection to be read
167  ****************************************************************************/
168 static void IPReadData(S_NETWORK_CONNECTION *ipc)
169 {
170  S32BIT bytes_free;
171  U8BIT *bufptr;
172  S32BIT bytes_read;
173 
174  FUNCTION_START(IPReadData);
175 
176  /* Check that there's space in the current recv buffer */
177  STB_OSMutexLock(ipc->recv_mutex);
178 
179  bytes_free = IP_RECV_BUFFER_SIZE - ipc->recv_num_bytes[ipc->fill_index];
180  if (bytes_free > 0)
181  {
182  bufptr = ipc->recv_buffer[ipc->fill_index] + ipc->recv_num_bytes[ipc->fill_index];
183  bytes_read = STB_NWReceive(ipc->socket, bufptr, bytes_free);
184  if (bytes_read > 0)
185  {
186  DBGPRINT("(0x%08lx): read %ld bytes into buffer %u", ipc->module, bytes_read, ipc->fill_index)
187 
188  ipc->recv_num_bytes[ipc->fill_index] += bytes_read;
189 
190  /* Send the buffer to the CI+ stack however much is in it */
191  if (!ipc->recv_buffer_sent)
192  {
193  DBGPRINT("(0x%08lx): Buffer %u ready, sending", ipc->module, ipc->fill_index)
194 
195  /* Send this buffer and switch to filling the next buffer */
196  ipc->send_index = ipc->fill_index;
197  ipc->fill_index = (ipc->fill_index + 1) % 2;
198 
199  if (STB_CIHandleIPData(ipc->module, ipc->recv_buffer[ipc->send_index],
200  ipc->recv_num_bytes[ipc->send_index]))
201  {
202  ipc->recv_buffer_sent = TRUE;
203  }
204  else
205  {
206  DBGPRINT(": STB_CIHandleIPData failed for module 0x%08lx", ipc->module)
207 
208  /* Data failed to be sent, so just mark the buffer empty */
209  ipc->recv_num_bytes[ipc->send_index] = 0;
210  }
211  }
212 #ifdef DEBUG_IP
213  else
214  {
215  DBGPRINT("(0x%08lx): Buffer %u ready but can't send", ipc->module, ipc->fill_index)
216  }
217 #endif
218  }
219  else
220  {
221  /* Server has closed the socket */
222  DBGPRINT("(0x%08lx): Read failed, closing the connection", ipc->module)
223  STB_CICloseIPConnection(ipc->module);
224  }
225  }
226 
227  STB_OSMutexUnlock(ipc->recv_mutex);
228 
229  FUNCTION_FINISH(IPReadData);
230 }
231 
232 /*!**************************************************************************
233  * @brief Background task that receives data from any open network connections
234  * @param param - unused
235  ****************************************************************************/
236 static void IPReceiveDataTask(void *param)
237 {
238  U8BIT i;
239  U16BIT num_socks;
240  S_NW_SOCKSET read_sockets;
241  S_NW_SOCKSET except_sockets;
242 
243  FUNCTION_START(IPReceiveDataTask);
244  USE_UNWANTED_PARAM(param);
245 
246  while (1)
247  {
248  STB_OSMutexLock(ip_mutex);
249 
250  num_socks = 0;
251  STB_NWSockZero(&read_sockets);
252  STB_NWSockZero(&except_sockets);
253 
254  for (i = 0; i < MAX_IP_CONNECTIONS; i++)
255  {
256  if (ip_connections[i].socket != NULL)
257  {
258  STB_NWSockSet(ip_connections[i].socket, &read_sockets);
259  STB_NWSockSet(ip_connections[i].socket, &except_sockets);
260  num_socks++;
261  }
262  }
263 
264  STB_OSMutexUnlock(ip_mutex);
265 
266  if (num_socks > 0)
267  {
268  if (STB_NWSelect(&read_sockets, NULL, &except_sockets, IP_RECV_TIMEOUT) > 0)
269  {
270  /* Find the sockets that have data available to be read */
271  STB_OSMutexLock(ip_mutex);
272 
273  for (i = 0; i < MAX_IP_CONNECTIONS; i++)
274  {
275  if (ip_connections[i].socket != NULL)
276  {
277  /* Check except socket first */
278  if (STB_NWSockIsSet(ip_connections[i].socket, &except_sockets))
279  {
280  DBGPRINT(" except socket %u", i)
281  }
282 
283  if (STB_NWSockIsSet(ip_connections[i].socket, &read_sockets))
284  {
285  /* Data available on this connection */
286  IPReadData(&ip_connections[i]);
287  }
288  }
289  }
290 
291  STB_OSMutexUnlock(ip_mutex);
292  }
293  }
294  else
295  {
296  /* No connections open, so just delay and check again */
297  STB_OSTaskDelay(IP_RECV_TIMEOUT);
298  }
299  }
300 
301  FUNCTION_FINISH(IPReceiveDataTask);
302 }
303 
304 #ifdef DEBUG_TRACING
305 static void PrintIPAddress(S_STB_CI_IP_ADDR *addr)
306 {
307  FUNCTION_START(PrintIPAddress);
308 
309  switch (addr->type)
310  {
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])
314  break;
315 
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])
324  break;
325 
326  case STB_CI_IP_ADDR_HOSTNAME:
327  PRINTDBG("\"%s\"", addr->data.hostname)
328  break;
329  }
330 
331  FUNCTION_FINISH(PrintIPAddress);
332 }
333 
334 #endif /* DEBUG_TRACING */
335 
336 
337 /*---global function definitions---------------------------------------------*/
338 
339 void CIP_GlueNetInitialise(void)
340 {
341  U16BIT i;
342 
343  ip_mutex = STB_OSCreateMutex();
344  if (ip_mutex != NULL)
345  {
346  for (i = 0; i != MAX_IP_CONNECTIONS; i++)
347  {
348  ip_connections[i].socket = NULL;
349  if ((ip_connections[i].send_data_sem = STB_OSCreateSemaphore()) != NULL)
350  {
351  STB_OSSemaphoreWait(ip_connections[i].send_data_sem);
352 
353  /* Create a background task to handle communications through the connection */
354  STB_OSCreateTask(IPSendDataTask, &ip_connections[i], IP_TASK_STACK_SIZE, IP_TASK_PRIORITY, (U8BIT *)"IPSendData");
355  }
356 
357  ip_connections[i].recv_mutex = STB_OSCreateMutex();
358  }
359  /* Create a background task to handle receiving of data on all connections */
360  STB_OSCreateTask(IPReceiveDataTask, NULL, IP_TASK_STACK_SIZE, IP_TASK_PRIORITY, (U8BIT *)"IPReceiveData");
361  }
362 }
363 
364 /*****************************************************************************
365  *
366  * Function Name: STB_CIGetMaxIPConnections
367  *
368  * Description: This function is called by the CI+ stack to find out how
369  * many simultaneous connections the host can support.
370  *
371  * If the host does not support IP connections, this function
372  * should return zero.
373  *
374  * Parameters: Nothing
375  *
376  * Returns: Number of simultaneous IP connections supported by the host
377  *
378  ****************************************************************************/
379 U16BIT STB_CIGetMaxIPConnections(void)
380 {
381  FUNCTION_START(STB_CIGetMaxIPConnections);
382  FUNCTION_FINISH(STB_CIGetMaxIPConnections);
383 
384  return MAX_IP_CONNECTIONS;
385 }
386 
387 /*****************************************************************************
388  *
389  * Function Name: STB_CIOpenIPConnection
390  *
391  * Description: This function is called by the CI+ stack to open an IP
392  * connection.
393  *
394  * When the connection is opened, the host must call
395  * STB_CINotifyIPStatus with STB_CI_IP_STATUS_CONNECTED.
396  *
397  * If the connection attempt times out, the host must call
398  * STB_CINotifyIPStatus with STB_CI_IP_STATUS_TIMEOUT.
399  *
400  * If the host cannot open the connection, it must call
401  * STB_CINotifyIPStatus with STB_CI_IP_STATUS_DISCONNECTED.
402  *
403  * Note: This function must not block
404  *
405  * Parameters: module - low-speed communication module
406  * addr - IP address or host name
407  * port - port number on server
408  * protocol - IP protocol (TCP or UDP)
409  * timeout - timeout in seconds
410  *
411  * Returns: Nothing
412  *
413  ****************************************************************************/
414 void STB_CIOpenIPConnection(U32BIT module, S_STB_CI_IP_ADDR *addr,
415  U16BIT port, E_STB_CI_IP_PROTOCOL protocol,
416  U8BIT timeout)
417 {
418  BOOLEAN connected = FALSE;
419  U8BIT index, i;
420  E_NW_PROTOCOL nw_protocol;
421  E_NW_AF af_type;
422  void *socket;
423  U8BIT address[48];
424  E_NW_ERROR err;
425  BOOLEAN valid;
426  U16BIT num_addrs;
427  S_NW_ADDR_INFO *nw_addrs;
428 
429  FUNCTION_START(STB_CIOpenIPConnection);
430  USE_UNWANTED_PARAM(timeout);
431 
432  if (ip_mutex == NULL)
433  {
434  CIP_GlueNetInitialise();
435  }
436 
437  for (index = 0; index < MAX_IP_CONNECTIONS; index++)
438  {
439  if (ip_connections[index].socket == NULL)
440  {
441  if (protocol == STB_CI_IP_PROTOCOL_TCP)
442  {
443  nw_protocol = NW_PROTOCOL_TCP;
444  }
445  else
446  {
447  nw_protocol = NW_PROTOCOL_UDP;
448  }
449 
450  valid = TRUE;
451 
452  switch (addr->type)
453  {
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]);
458  break;
459 
460  case STB_CI_IP_ADDR_HOSTNAME:
461  if ((num_addrs = STB_NWLookupAddress(addr->data.hostname, &nw_addrs)) > 0)
462  {
463  valid = FALSE;
464 
465  for (i = 0; (i < num_addrs) && !valid; i++)
466  {
467  if (nw_addrs[i].type == NW_SOCK_STREAM)
468  {
469  /* Found an address that can be used */
470  af_type = nw_addrs[i].af;
471  nw_protocol = nw_addrs[i].protocol;
472  strcpy((char *)address, (char *)nw_addrs[i].addr);
473  valid = TRUE;
474  }
475  }
476 
477  STB_MEMFreeSysRAM(nw_addrs);
478  }
479  else
480  {
481  valid = FALSE;
482  }
483  break;
484 
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]);
494  break;
495 
496  default:
497  valid = FALSE;
498  break;
499  }
500 
501  if (valid)
502  {
503  if ((socket = STB_NWOpenSocket(af_type, NW_SOCK_STREAM, nw_protocol, FALSE)) != NULL)
504  {
505  if ((err = STB_NWConnect(socket, address, port)) == NW_OK)
506  {
507  STB_OSMutexLock(ip_mutex);
508 
509  /* Have found a connection that can be used and have connected successfully */
510  ip_connections[index].socket = socket;
511  ip_connections[index].module = module;
512 
513  STB_OSMutexLock(ip_connections[index].recv_mutex);
514 
515  /* Allocate memory for the receive buffers */
516  for (i = 0; i < 2; i++)
517  {
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)
521  {
522  DBGPRINT("(0x%08x): Failed to allocate memory for receive buffer", module)
523  }
524  }
525 
526  ip_connections[index].fill_index = 0;
527  ip_connections[index].send_index = 0;
528  ip_connections[index].recv_buffer_sent = FALSE;
529 
530  STB_OSMutexUnlock(ip_connections[index].recv_mutex);
531 
532  STB_OSMutexUnlock(ip_mutex);
533 
534  DBGPRINT("(0x%08x): Successfully connected to \"%s\", port %u",
535  module, address, port)
536 
537  STB_CINotifyIPStatus(module, STB_CI_IP_STATUS_CONNECTED);
538 
539  connected = TRUE;
540  break;
541  }
542  else
543  {
544  /* Failed to connect, so close the socket */
545  STB_NWCloseSocket(socket);
546  DBGPRINT("(0x%08x): Failed to connect to \"%s\", port %u",
547  module, address, port)
548  break;
549  }
550  }
551  else
552  {
553  DBGPRINT("(0x%08x): Failed to open socket", module)
554  break;
555  }
556  }
557  }
558  }
559 
560  if (!connected)
561  {
562  #ifdef DEBUG_TRACING
563  if (index >= MAX_IP_CONNECTIONS)
564  {
565  DBGPRINT("(0x%08x): No more connections available to connect to ", module)
566  PrintIPAddress(addr);
567  }
568  #endif
569 
570  STB_CINotifyIPStatus(module, STB_CI_IP_STATUS_DISCONNECTED);
571  }
572 
573  FUNCTION_FINISH(STB_CIOpenIPConnection);
574 }
575 
576 /*****************************************************************************
577  *
578  * Function Name: STB_CISendIPData
579  *
580  * Description: This function is called by the CI+ stack to send data to an
581  * IP connection.
582  *
583  * The host is responsible for sending the data (as one block,
584  * if possible). If some of the data cannot be sent, the host
585  * must retry until the entire buffer is sent.
586  *
587  * Once the buffer is sent, the host must call the function
588  * STB_CINotifyIPStatus to inform the CI+ stack. The buffer
589  * remains valid until the host calls the notification
590  * function. The CI+ stack does not call this function again
591  * until it receives a notification from the host.
592  *
593  * Note: This function must not block
594  *
595  * Parameters: module - low-speed communication module
596  * buffer - the buffer to send
597  * len - number of bytes to send
598  *
599  * Returns: Nothing
600  *
601  ****************************************************************************/
602 void STB_CISendIPData(U32BIT module, U8BIT *buffer, U16BIT len)
603 {
605 
606  FUNCTION_START(STB_CISendIPData);
607 
608  if ((ipc = FindIPConnection(module)) != NULL)
609  {
610  if (ipc->socket != NULL)
611  {
612  DBGPRINT("(0x%08x): len=%u", module, len)
613 
614  /* As the buffer is guaranteed to be valid until the send has completed,
615  * the address can just be passed to the background task */
616  ipc->send_buffer = buffer;
617  ipc->send_length = len;
618 
619  STB_OSSemaphoreSignal(ipc->send_data_sem);
620  }
621  }
622 
623  FUNCTION_FINISH(STB_CISendIPData);
624 }
625 
626 /*****************************************************************************
627  *
628  * Function Name: STB_CIReleaseIPData
629  *
630  * Description: This function is called by the CI+ stack to inform the
631  * host that the IP data can be released.
632  *
633  * This function is called once all the data provided by
634  * STB_CIHandleIPData has been consumed.
635  *
636  * Parameters: module - low-speed communication module
637  * buffer - data buffer to release
638  *
639  * Returns: Nothing
640  *
641  ****************************************************************************/
642 void STB_CIReleaseIPData(U32BIT module, U8BIT *buffer)
643 {
645 
646  FUNCTION_START(STB_CIReleaseIPData);
647  USE_UNWANTED_PARAM(buffer);
648 
649  if ((ipc = FindIPConnection(module)) != NULL)
650  {
651  STB_OSMutexLock(ipc->recv_mutex);
652 
653 #ifdef DEBUG_TRACING
654  if (ipc->recv_buffer[ipc->send_index] != buffer)
655  {
656  DBGPRINT("(0x%08lx): Expected buffer %u(%p) but received buffer %p", module,
657  ipc->send_index, ipc->recv_buffer[ipc->send_index], buffer)
658  }
659  else
660  {
661  DBGPRINT("(0x%08lx): Buffer %u", module, ipc->send_index)
662  }
663 #endif
664 
665  ipc->recv_buffer_sent = FALSE;
666  ipc->recv_num_bytes[ipc->send_index] = 0;
667 
668  /* Check to see if there's another buffer waiting to be sent */
669  ipc->send_index = (ipc->send_index + 1) % 2;
670 
671  if (ipc->recv_num_bytes[ipc->send_index] > 0)
672  {
673  DBGPRINT("(0x%08lx): Sending buffer %u", module, ipc->send_index)
674 
675  if (STB_CIHandleIPData(ipc->module, ipc->recv_buffer[ipc->send_index],
676  ipc->recv_num_bytes[ipc->send_index]))
677  {
678  ipc->recv_buffer_sent = TRUE;
679 
680  /* If this buffer is the one that was being filled then need to switch buffers */
681  if (ipc->fill_index == ipc->send_index)
682  {
683  /* Switch the buffer being filled */
684  ipc->fill_index = (ipc->fill_index + 1) % 2;
685  }
686  }
687  else
688  {
689  DBGPRINT("(0x%08lx): STB_CIHandleIPData failed", module)
690 
691  /* CI+ stack didn't want the data so mark the buffer as empty */
692  ipc->recv_num_bytes[ipc->send_index] = 0;
693  }
694  }
695 
696  STB_OSMutexUnlock(ipc->recv_mutex);
697  }
698 
699  FUNCTION_FINISH(STB_CIReleaseIPData);
700 }
701 
702 /*****************************************************************************
703  *
704  * Function Name: STB_CICloseIPConnection
705  *
706  * Description: This function is called by the CI+ stack to close an IP
707  * connection.
708  *
709  * Parameters: module - low-speed communication module
710  *
711  * Returns: Nothing
712  *
713  ****************************************************************************/
714 void STB_CICloseIPConnection(U32BIT module)
715 {
717  U8BIT i;
718 
719  FUNCTION_START(STB_CICloseIPConnection);
720 
721  DBGPRINT("(0x%08x)", module)
722 
723  if ((ipc = FindIPConnection(module)) != NULL)
724  {
725  if (ipc->socket != NULL)
726  {
727  STB_OSMutexLock(ip_mutex);
728 
729  if (!STB_NWCloseSocket(ipc->socket))
730  {
731  DBGPRINT("(0x%08x) STB_NWCloseSocket failed", module)
732  }
733  ipc->socket = NULL;
734 
735  STB_OSMutexLock(ipc->recv_mutex);
736 
737  /* Any received data is no longer required so can be thrown away */
738  for (i = 0; i < 2; i++)
739  {
740  if (ipc->recv_buffer[i] != NULL)
741  {
742  STB_MEMFreeSysRAM(ipc->recv_buffer[i]);
743  ipc->recv_buffer[i] = NULL;
744  }
745  }
746 
747  STB_OSMutexUnlock(ipc->recv_mutex);
748 
749  STB_OSMutexUnlock(ip_mutex);
750 
751  STB_CINotifyIPStatus(module, STB_CI_IP_STATUS_DISCONNECTED);
752  }
753  }
754 
755  FUNCTION_FINISH(STB_CICloseIPConnection);
756 }
757 
768 void STB_CIGetCommsIPConfig(S_STB_CI_COMMS_IP_CONFIG *comms_ip_config)
769 {
770  FUNCTION_START(STB_CIGetCommsIPConfig);
771  USE_UNWANTED_PARAM(comms_ip_config);
772  FUNCTION_FINISH(STB_CIGetCommsIPConfig);
773 }
774 
790  COMMS_IP_CONFIG_IP_ARRAY_T *DNS_server_to_populate)
791 {
793  USE_UNWANTED_PARAM(index);
794  USE_UNWANTED_PARAM(DNS_server_to_populate);
796  return FALSE;
797 }
798 
799 
817 BOOLEAN STB_CIOpenMulticastConnection(U32BIT module,
818  S_STB_CI_MULTICAST_DESCRIPTOR *descriptor,
819  U8BIT timeout)
820 {
821  FUNCTION_START(STB_CIOpenMulticastConnection);
822  USE_UNWANTED_PARAM(module);
823  USE_UNWANTED_PARAM(descriptor);
824  USE_UNWANTED_PARAM(timeout);
825  FUNCTION_FINISH(STB_CIOpenMulticastConnection);
826  return FALSE;
827 }
828 
829 
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.
Socket functions.
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. &#39;leave&#39;, &#39;signal&#39; or &#39;release&#39;)
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...
Definition: ci_glue_net.c:817
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...
Definition: ci_glue_net.c:768
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. &#39;enter&#39;, &#39;wait&#39; or &#39;get&#39;).
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...
Definition: ci_glue_net.c:789
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.
#define DBGPRINT(...)
Definition: dbgfuncs.h:74