25 #if defined(INCLUDE_IC) 41 #ifndef HTTP_STACK_SIZE 42 #define HTTP_STACK_SIZE 4096 46 #define HTTP_TIMEOUT 45 49 #define HTTP_QUEUE_SIZE 512 50 #define HTTP_FAILURE_TIMEOUT 500 51 #define REQUEST_START_TIMEOUT 500 52 #define HTTP_IDLE_TIMEOUT 200 53 #define MAX_RANGE_LEN 255 57 #define DBG_ENTRY(x) DBG_PRINTF(" >> %s\n", #x); 58 #define DBG_EXIT(x) DBG_PRINTF(" << %s\n", #x); 64 #define MAX_USER_AGENT 256 69 typedef enum HttpRequestCmd_tag
77 struct HttpRequest_tag
79 struct HttpRequest_tag *next;
80 HttpCallback_t header_cb;
81 HttpCallback_t callback;
88 U8BIT range[MAX_RANGE_LEN];
93 typedef struct HttpTaskCmd_tag
95 HttpRequest_t request;
96 HttpRequestCmd_t kind;
103 HTTP_TASK_STOP_REQUEST
109 static void *http_task_handle = NULL;
110 static enum HttpTaskStatus_t http_task_status = HTTP_TASK_STOPPED;
111 static void *http_task_semaphore = NULL;
112 static void *http_task_mutex = NULL;
113 static void *http_task_queue = NULL;
115 static HttpRequest_t http_request_list = NULL;
116 static U32BIT http_cert_count = 0;
117 static U8BIT http_user_agent[MAX_USER_AGENT + 1] = { 0 };
122 static void httpSetRequestUrl(U8BIT *requrl, U8BIT *url);
123 static void httpSetupCache(HttpRequest_t request, U8BIT cachePriority);
124 static BOOLEAN httpStartTask(U32BIT taskPriority);
125 static void httpStopTask(
void);
126 static void httpTaskMain(
void *task_arg);
127 static void httpAddRequest(HttpRequest_t request);
128 static void httpContinueRequest(HttpRequest_t request);
129 static void httpRemoveRequest(HttpRequest_t request);
130 static U16BIT httpProcessRequests(
void);
131 static BOOLEAN httpIsValidRequest(HttpRequest_t request);
134 static void httpPrintRequestList(
void);
137 static void httpCookieParse(
void *data, U32BIT data_len,
char *url);
138 static U8BIT* httpCookieGenerateHeader(U8BIT *url);
139 static void httpCookieAckHeader(U8BIT *header);
143 httpCookieGenerateHeader,
154 E_HttpErr
httpOpen(U32BIT task_priority)
161 if (http_task_semaphore != NULL)
168 if (http_task_semaphore == NULL)
170 err = HTTP_ERR_INTERNAL;
177 if (http_task_mutex == NULL)
179 err = HTTP_ERR_INTERNAL;
181 http_task_semaphore = NULL;
186 if (http_task_queue == NULL)
188 err = HTTP_ERR_INTERNAL;
190 http_task_mutex = NULL;
192 http_task_semaphore = NULL;
199 TRACE(TFILE,(
"Set timeout"));
201 success = httpStartTask(task_priority);
204 TRACE(TERROR,(
"Start task failed"));
207 http_task_queue = NULL;
209 http_task_mutex = NULL;
211 http_task_semaphore = NULL;
212 err = HTTP_ERR_INTERNAL;
217 TRACE(TERROR,(
"Init failed err=%d",err));
238 cookie_manager = *manager;
243 cookie_manager.parse = httpCookieParse;
244 cookie_manager.generate_header = httpCookieGenerateHeader;
245 cookie_manager.ack_header = httpCookieAckHeader;
258 len = strlen((
char *)user_agent);
259 if (len > MAX_USER_AGENT)
261 len = MAX_USER_AGENT;
263 memcpy(http_user_agent, user_agent, len);
264 http_user_agent[len] =
'\0';
311 return http_cert_count;
327 HttpCallback_t callback,
328 U32BIT request_id,
void *userdata)
330 HttpRequest_t request;
338 TRACE(TERROR, (
"Malloc failed"));
343 if (request->url != NULL)
345 httpSetRequestUrl(request->url, url);
347 request->next = NULL;
348 request->header_cb = NULL;
349 request->callback = callback;
350 request->request_id = request_id;
351 request->response_code = 0;
352 request->userdata = userdata;
353 request->postdata = NULL;
354 request->postdata_len = 0;
355 request->processing = FALSE;
358 if (request->handle != NULL)
360 TRACE(TFILE, (
"HP_CreateRequest %p returned=%p URL=%s", request, request->handle, request->url));
363 header = cookie_manager.generate_header((U8BIT *)request->url);
367 cookie_manager.ack_header(header);
370 httpSetupCache(request, cachePriority);
374 TRACE(TERROR, (
"HP_CreateRequest failed"));
401 U32BIT request_id,
void *userdata)
403 HttpRequest_t request;
412 if (request->url != NULL)
414 httpSetRequestUrl(request->url, url);
416 request->next = NULL;
417 request->header_cb = callback;
418 request->callback = callback;
419 request->request_id = request_id;
420 request->response_code = 0;
421 request->userdata = userdata;
422 request->postdata = NULL;
423 request->postdata_len = 0;
424 request->processing = FALSE;
427 if (request->handle != NULL)
429 TRACE(TFILE, (
"HP_CreateRequest %p returned=%p URL=%s", request, request->handle,request->url));
432 header = cookie_manager.generate_header((U8BIT *)request->url);
436 cookie_manager.ack_header(header);
441 TRACE(TERROR, (
"HP_CreateRequest failed"));
448 TRACE(TERROR, (
"memory fail"));
471 HttpCallback_t callback,
472 U32BIT request_id,
void *userdata)
474 HttpRequest_t request;
485 if (request->url != NULL)
487 httpSetRequestUrl(request->url, url);
489 request->next = NULL;
490 request->header_cb = NULL;
491 request->callback = callback;
492 request->request_id = request_id;
493 request->response_code = 0;
494 request->userdata = userdata;
495 request->processing = FALSE;
499 request->postdata_len = strlen((
char *)data);
500 request->postdata = STR_DataAlloc(request->postdata_len);
501 if (request->postdata != NULL)
503 memcpy(request->postdata, data, request->postdata_len);
507 request->postdata_len = 0;
512 request->postdata = NULL;
513 request->postdata_len = 0;
517 if (request->handle != NULL)
519 TRACE(TFILE, (
"HP_CreateRequest %p returned=%p", request, request->handle));
524 header = cookie_manager.generate_header((U8BIT *)request->url);
528 cookie_manager.ack_header(header);
531 if (request->postdata != NULL)
536 TRACE(TERROR, (
"HP_SetPostData failed %p",err));
543 TRACE(TFILE, (
"Destroying Request hdl=%p", request->handle));
545 if (request->postdata != NULL)
547 STR_DataFree(request->postdata, request->postdata_len);
555 TRACE(TERROR, (
"HP_CreateRequest failed"));
584 HttpCallback_t header_callback,
585 HttpCallback_t callback,
586 U32BIT request_id,
void *userdata)
588 HttpRequest_t request;
597 if (request->url != NULL)
599 httpSetRequestUrl(request->url, url);
601 request->next = NULL;
602 request->header_cb = header_callback;
603 request->callback = callback;
604 request->request_id = request_id;
605 request->response_code = 0;
606 request->userdata = userdata;
607 request->postdata = NULL;
608 request->postdata_len = 0;
609 request->processing = FALSE;
612 if (request->handle != NULL)
614 TRACE(TICS, (
"HP_CreateRequest %p returned=%p URL=%s", request, request->handle, request->url));
617 header = cookie_manager.generate_header((U8BIT *)request->url);
621 cookie_manager.ack_header(header);
624 request->range[0] =
'\0';
627 strcpy((
char *)request->range, (
char *)range);
633 TRACE(TERROR, (
"HP_CreateRequest failed"));
664 cmd.request = request;
665 cmd.kind = HTTP_REQUEST_ADD;
667 TRACE(TICS, (
"%p hdl=%p", request, request->handle));
672 REQUEST_START_TIMEOUT);
675 TRACE(TERROR,(
"Cannot add to queue, retrying"));
699 cmd.request = request;
700 cmd.kind = HTTP_REQUEST_RESUME;
702 TRACE(TFILE, (
"%p hdl=%p", request, request->handle));
707 REQUEST_START_TIMEOUT);
710 TRACE(TERROR,(
"Cannot resume to queue, retrying"));
751 cmd.request = request;
752 cmd.kind = HTTP_REQUEST_REMOVE;
754 TRACE(TICS, (
"%p hdl=%p", request, request->handle));
759 REQUEST_START_TIMEOUT);
766 TRACE(TICS, (
"Stopped Request %p", request));
779 assert(request != NULL);
780 assert(request->handle != NULL);
782 TRACE(TICS, (
"Destroying Request hdl=%p", request->handle));
784 if (request->postdata != NULL)
786 STR_DataFree(request->postdata, request->postdata_len);
807 #ifndef DISABLE_HTTP_CLOSEDOWN 812 http_task_semaphore = NULL;
827 static void httpSetRequestUrl(U8BIT *requrl, U8BIT *url)
829 static char lowercase[] =
"abcdefghijklmnopqrstuvwxyz";
830 static char uppercase[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
834 DBG_ENTRY(httpSetRequestUrl);
836 strcpy((
char *)requrl, (
char *)url);
841 p = strstr((
char *)requrl,
"://");
844 for (p += 3; *p !=
'/' && *p !=
'\0'; p++)
848 sp = strchr(uppercase, c);
851 idx = sp - uppercase;
857 DBG_EXIT(httpSetRequestUrl);
868 static void httpSetupCache(HttpRequest_t request, U8BIT cachePriority)
870 if (cachePriority == 0)
873 HP_AddHeader(request->handle, (U8BIT *)
"Cache-Control: no-cache, no-transform");
874 HP_AddHeader(request->handle, (U8BIT *)
"Pragma: no-cache");
876 else if (cachePriority % 2 == 0)
879 HP_AddHeader(request->handle, (U8BIT *)
"Cache-Control: max-stale, no-transform");
884 HP_AddHeader(request->handle, (U8BIT *)
"Cache-Control: no-transform");
892 static BOOLEAN httpStartTask(U32BIT taskPriority)
896 DBG_ENTRY(httpStartTask);
899 (U8BIT)taskPriority, (U8BIT *)
"HTTP");
900 if (http_task_handle != NULL)
906 DBG_EXIT(httpStartTask);
915 static void httpStopTask(
void)
917 DBG_ENTRY(httpStopTask);
919 if (http_task_status == HTTP_TASK_RUNNING)
921 http_task_status = HTTP_TASK_STOP_REQUEST;
924 assert(http_task_status == HTTP_TASK_STOPPED);
927 DBG_EXIT(httpStopTask);
934 static void httpTaskMain(
void *task_arg)
940 DBG_ENTRY(httpTaskMain);
942 http_task_status = HTTP_TASK_RUNNING;
945 while (http_task_status == HTTP_TASK_RUNNING)
947 count = httpProcessRequests();
959 while (success || count > 0)
966 case HTTP_REQUEST_ADD:
967 httpAddRequest(cmd.request);
969 case HTTP_REQUEST_RESUME:
970 httpContinueRequest(cmd.request);
972 case HTTP_REQUEST_REMOVE:
973 httpRemoveRequest(cmd.request);
976 case HTTP_REQUEST_NONE:
983 count = httpProcessRequests();
989 if (http_task_status == HTTP_TASK_STOP_REQUEST)
991 http_task_status = HTTP_TASK_STOPPED;
996 DBG_EXIT(httpTaskMain);
1004 static void httpAddRequest(HttpRequest_t request)
1007 HttpRequest_t *p_request;
1010 DBG_ENTRY(httpAddRequest);
1013 httpPrintRequestList();
1015 if (request == NULL)
1017 TRACE(TERROR, (
"request is NULL!"));
1021 TRACE(TICS, (
"Start request hdl=%p", request->handle));
1026 p_request = &http_request_list;
1027 while (*p_request != NULL)
1029 p_request = &(*p_request)->next;
1031 *p_request = request;
1038 TRACE(TERROR, (
"HP_StartRequest failed %d",err));
1041 httpPrintRequestList();
1044 DBG_EXIT(httpAddRequest);
1052 static void httpContinueRequest(HttpRequest_t request)
1054 DBG_ENTRY(httpContinueRequest);
1056 if (httpIsValidRequest(request))
1058 if (!request->processing)
1060 TRACE(TICS, (
"Resuming request hdl=%p", request->handle));
1065 TRACE(TICS, (
"Resume not needed hdl=%p", request->handle));
1069 DBG_EXIT(httpContinueRequest);
1077 static void httpRemoveRequest(HttpRequest_t request)
1079 HttpRequest_t *p_request;
1082 DBG_ENTRY(httpRemoveRequest);
1085 httpPrintRequestList();
1088 if (!httpIsValidRequest(request))
1090 TRACE(TERROR,(
"request %p was not found", request))
1094 TRACE(TICS, (
"Stop request %p hdl=%p", request, request->handle));
1098 TRACE(TERROR,(
"HP_StopRequest for request %p failed err=%d - removing anyway", request, err))
1103 p_request = &http_request_list;
1104 while (*p_request != NULL)
1106 if (*p_request == request)
1108 *p_request = request->next;
1109 request->next = NULL;
1112 p_request = &(*p_request)->next;
1116 httpPrintRequestList();
1124 DBG_EXIT(httpRemoveRequest);
1131 static U16BIT httpProcessRequests(
void)
1133 U16BIT running_handles;
1135 DBG_ENTRY(httpProcessRequests);
1140 DBG_EXIT(httpProcessRequests);
1142 return running_handles;
1156 HttpRequest_t request;
1163 request->response_code = code;
1164 cookie_manager.parse(data, len, (
char *)request->url);
1166 if (request->header_cb != NULL && data != NULL && len > 0)
1168 response.status = HTTP_STATUS_WAIT;
1169 response.code = code;
1170 response.data = data;
1171 response.data_len = len;
1172 request->header_cb(request->userdata, request->request_id, &response);
1193 HttpRequest_t request;
1195 BOOLEAN processed = TRUE;
1200 if (request->callback != NULL)
1202 response.status = HTTP_STATUS_WAIT;
1204 response.data = data;
1205 response.data_len = len;
1206 processed = request->callback(request->userdata, request->request_id,
1208 request->processing = processed;
1225 HttpRequest_t request;
1231 if (request->callback != NULL)
1233 response.status = status;
1234 response.code = request->response_code;
1235 response.data = NULL;
1236 response.data_len = 0;
1237 request->callback(request->userdata, request->request_id, &response);
1251 static BOOLEAN httpIsValidRequest(HttpRequest_t request)
1253 HttpRequest_t current;
1258 current = http_request_list;
1259 while (current != NULL)
1261 if (current == request)
1266 current = current->next;
1277 static void httpPrintRequestList(
void)
1279 HttpRequest_t request;
1281 request = http_request_list;
1282 while (request != NULL)
1284 DBG_PRINTF(
"%p -> ", request); fflush(stdout);
1285 request = request->next;
1287 DBG_PRINTF(
"||\n"); fflush(stdout);
1299 static void httpCookieParse(
void *data, U32BIT data_len,
char *url)
1309 static U8BIT* httpCookieGenerateHeader(U8BIT *url)
1319 static void httpCookieAckHeader(U8BIT *header)
void STB_OSSemaphoreWait(void *semaphore)
Wait on Semaphore Indefinity or Until Released.
void httpSetCookieManager(HttpCookieManager_t *manager)
Set cookie manager for HTTP connections.
void httpStartRequest(HttpRequest_t request)
Start an HTTP request. Everything related to the request is passed through the callback that was regi...
Manages the interface between MHEG5 Engine and the HTTP component.
void STB_OSTaskDelay(U16BIT timeout)
Delay Task for Specifed Time Period.
void STB_MemFree(void *ptr)
Releases previously allocated memory.
void STB_OSDeleteMutex(void *mutex)
Delete a mutex.
HttpRequest_t httpCreateHeadRequest(U8BIT *url, HttpCallback_t callback, U32BIT request_id, void *userdata)
Create an HTTP HEAD request.
E_HttpErr httpOpen(U32BIT task_priority)
Open the HTTP interface.
BOOLEAN STB_OSDestroyQueue(void *queue)
Destroy Queue.
BOOLEAN STB_OSWriteQueue(void *queue, void *msg, U16BIT msg_size, U16BIT timeout)
Write a message to the queue.
void * STB_MemAlloc(U32BIT memSize)
Allocates the specified number of bytes.
U8BIT * httpGetRequestRedirect(HttpRequest_t request)
Return the URL that the request is redirected to (valid only for response codes of 3xx)...
void * STB_OSCreateSemaphore(void)
Create a Binary Semaphore. That is maximum value of 1. The initial value should be 1...
HttpRequest_t httpCreatePostRequest(U8BIT *url, U8BIT *data, HttpCallback_t callback, U32BIT request_id, void *userdata)
Create an HTTP POST request.
void * STB_OSCreateQueue(U16BIT msg_size, U16BIT msg_max)
Create Queue of given number of messages and size of message.
void * STB_OSCreateMutex(void)
Create a mutex.
BOOLEAN STB_OSReadQueue(void *queue, void *msg, U16BIT msg_size, U16BIT timeout)
Read a message from a queue.
void httpStopRequest(HttpRequest_t request)
Stop an HTTP request. This function does not destroy the request; this is done using httpDestroyReque...
void httpClearTlsCertStore(void)
Clear TLS certificate store.
void httpResumeRequest(HttpRequest_t request)
Resume an HTTP request. A request can be paused by returning FALSE from the content callback to tell ...
void httpDestroyRequest(HttpRequest_t request)
Destroy an HTTP request.
void httpSetUserAgent(U8BIT *user_agent)
Set User Agent for HTTP connections.
void httpClose(void)
Close the HTTP interface.
void httpAddTlsCertToStore(U8BIT *certData, U32BIT certLen)
Add TLS certificate to store.
HttpRequest_t httpCreateStreamRequest(U8BIT *url, U8BIT *range, HttpCallback_t header_callback, HttpCallback_t callback, U32BIT request_id, void *userdata)
Create an HTTP request for stream media.
References: [1] UK1 Profile - Digital Terrestrial Television - Requirements for interoperability (The...
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...
U32BIT httpGetTlsCertStoreCount(void)
Return number of TLS certificate in the certificate store.
HttpRequest_t httpCreateGetRequest(U8BIT *url, U8BIT cachePriority, HttpCallback_t callback, U32BIT request_id, void *userdata)
Create an HTTP GET request.
Engine support utility functions for MHEG5.
void STB_OSDestroyTask(void *task)
Delete Task must be called upon termination of each task as it frees all OS specific resources alloca...
void STB_OSDeleteSemaphore(void *semaphore)
Delete a Semaphore.
void STB_OSSemaphoreSignal(void *semaphore)
Signal a Semaphore to Release it by decrementing its counter.
Header file - Function prototypes for operating system.