File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / miniupnpd / miniupnpc-libuv / minissdpc-libuv.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Sep 27 11:25:11 2023 UTC (9 months, 1 week ago) by misho
Branches: miniupnpd, MAIN
CVS tags: v2_3_3p0, HEAD
Version 2.3.3p0

    1: /* $Id: minissdpc-libuv.c,v 1.1.1.1 2023/09/27 11:25:11 misho Exp $ */
    2: /* vim: tabstop=4 shiftwidth=4 noexpandtab
    3:  * Project : miniupnp
    4:  * Web : http://miniupnp.free.fr/
    5:  * Author : Thomas BERNARD
    6:  * copyright (c) 2005-2019 Thomas Bernard
    7:  * This software is subjet to the conditions detailed in the
    8:  * provided LICENCE file. */
    9: #include <stdio.h>
   10: #include <stdlib.h>
   11: #include <string.h>
   12: 
   13: #include "minissdpc-libuv.h"
   14: 
   15: #include "codelength.h"
   16: #include <uv.h>
   17: 
   18: struct userdata_s
   19: {
   20: 	void* cb;
   21: 	void* userdata;
   22: };
   23: 
   24: static void connect_cb(uv_connect_t* req, int status)
   25: {
   26: 	uv_stream_t *stream = req->handle;
   27: 	struct userdata_s *us = stream->data;
   28: 	void(*user_connect_cb)(void*, void*) = us->cb;
   29: 
   30: 	if(status < 0)
   31: 		user_connect_cb(0, us->userdata);
   32: 	else
   33: 		user_connect_cb(req->handle, us->userdata);
   34: 
   35: 	free(req);
   36: 	free(us);
   37: 
   38: 	if(status < 0)
   39: 		free(stream);
   40: }
   41: 
   42: int
   43: connectToMiniSSDPD(const char * socketpath, void(*user_connect_cb)(void* connect, void* userdata), void *userdata)
   44: {
   45: 	if(user_connect_cb == 0)
   46: 		return MINISSDPC_INVALID_INPUT;
   47: 
   48: 	if(!socketpath)
   49: 		socketpath = "/var/run/minissdpd.sock";
   50: 
   51: 	uv_pipe_t *p = malloc(sizeof(uv_pipe_t));
   52: 
   53: 	if(uv_pipe_init(uv_default_loop(), p, 1) < 0)
   54: 		return MINISSDPC_SOCKET_ERROR;
   55: 
   56: 	uv_connect_t *conn = malloc(sizeof(uv_connect_t));
   57: 	struct userdata_s *us = malloc(sizeof(struct userdata_s));
   58: 	us->cb = user_connect_cb;
   59: 	us->userdata = userdata;
   60: 	p->data = us;
   61: 	uv_pipe_connect(conn, p, socketpath, &connect_cb);
   62: 	return MINISSDPC_SUCCESS;
   63: }
   64: 
   65: static void
   66: close_cb(uv_handle_t *handle)
   67: {
   68: 	free(handle);
   69: }
   70: 
   71: MINIUPNP_LIBSPEC void
   72: disconnectFromMiniSSDPD(void *session)
   73: {
   74: 	uv_close((uv_handle_t *)session, close_cb);
   75: }
   76: 
   77: static void write_cb(uv_write_t* req, int status)
   78: {
   79: 	uv_stream_t* stream = req->handle;
   80: 	struct userdata_s *us = stream->data;
   81: 	void(*user_write_cb)(void*, int, void*) = us->cb;
   82: 	user_write_cb(req->handle, status == 0, us->userdata);
   83: 	// free(req->bufs->base);
   84: 	free(req);
   85: 	free(us);
   86: }
   87: 
   88: MINIUPNP_LIBSPEC int
   89: requestDevicesFromMiniSSDPD(void *session, const char * devtype, void(*requestFinish)(void *connect, int success, void* userdata), void* userdata)
   90: {
   91: 	char *buffer;
   92: 	char *p;
   93: 	unsigned int stsize;
   94: 
   95: 	if (devtype == NULL)
   96: 	{
   97: 		return MINISSDPC_UNKNOWN_ERROR;
   98: 	}
   99: 	stsize = strlen(devtype);
  100: 
  101: 	buffer = malloc(256);
  102: 	if(buffer == NULL)
  103: 	{
  104: 		return MINISSDPC_MEMORY_ERROR;
  105: 	}
  106: 	p = buffer;
  107: 
  108: 	if(stsize == 8 && 0 == memcmp(devtype, "ssdp:all", 8))
  109: 	{
  110: 		buffer[0] = 3;  /* request type 3 : everything */
  111: 	}
  112: 	else
  113: 	{
  114: 		buffer[0] = 1; /* request type 1 : request devices/services by type */
  115: 	}
  116: 
  117: 	p++;
  118: 	unsigned int l = stsize;
  119: 	CODELENGTH(l, p);
  120: 
  121: 	if(p + stsize > buffer + 256)
  122: 	{
  123: 		/* devtype is too long ! */
  124: 		#ifdef DEBUG
  125: 		fprintf(stderr, "devtype is too long ! stsize=%u sizeof(buffer)=%u\n",
  126: 		        stsize, (unsigned)sizeof(buffer));
  127: 		#endif /* DEBUG */
  128: 		free(buffer);
  129: 		return MINISSDPC_INVALID_INPUT;
  130: 	}
  131: 
  132: 	memcpy(p, devtype, stsize);
  133: 	p += stsize;
  134: 	uv_write_t *req = malloc(sizeof(uv_write_t));
  135: 
  136: 	if(req == NULL)
  137: 	{
  138: 		free(buffer);
  139: 		return MINISSDPC_MEMORY_ERROR;
  140: 	}
  141: 
  142: 	struct userdata_s *us = malloc(sizeof(struct userdata_s));
  143: 
  144: 	if(us == NULL)
  145: 	{
  146: 		free(req);
  147: 		free(buffer);
  148: 		return MINISSDPC_MEMORY_ERROR;
  149: 	}
  150: 
  151: 	us->cb = requestFinish;
  152: 	us->userdata = userdata;
  153: 	uv_stream_t* stream = session;
  154: 	stream->data = us;
  155: 	uv_buf_t data[] =
  156: 	{
  157: 		{ .base = buffer, .len = p - buffer }
  158: 	};
  159: 	uv_write(req, stream, data, 1, write_cb);
  160: 	return MINISSDPC_SUCCESS;
  161: }
  162: 
  163: static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf)
  164: {
  165: 	(void)handle;
  166: 	buf->base = malloc(size);
  167: 	buf->len = size;
  168: }
  169: 
  170: static void read_cb(uv_stream_t *stream, ssize_t size, const uv_buf_t* buffer)
  171: {
  172: 	struct userdata_s *us = stream->data;
  173: 	void(*user_write_cb)(void *connect, void *userdata, struct UPNPDev*) = us->cb;
  174: 	struct UPNPDev * devlist = NULL;
  175: 	char * p = buffer->base;
  176: 	unsigned int i, ndev;
  177: 
  178: 	if(size == 0)
  179: 	{
  180: 		return;
  181: 	}
  182: 
  183: 	if(size < 0)
  184: 	{
  185: 		user_write_cb(stream, us->userdata, devlist);
  186: 		uv_read_stop(stream);
  187: 		free(us);
  188: 		stream->data = NULL;
  189: 		return;
  190: 	}
  191: 
  192: 	ndev = *p;
  193: 	p++;
  194: 
  195: 	for(i = 0; i < ndev; i++)
  196: 	{
  197: 		unsigned int urlsize;
  198: 		char *url = NULL;
  199: 		unsigned int stsize;
  200: 		char *st = NULL;
  201: 		unsigned int usnsize;
  202: 		char *usn = NULL;
  203: 
  204: 		DECODELENGTH(urlsize, p);
  205: 		if(size != 0)
  206: 		{
  207: 			url = strndup(p, urlsize);
  208: 
  209: 			if(url == NULL)
  210: 				break;
  211: 		}
  212: 		p += urlsize;
  213: 
  214: 		DECODELENGTH(stsize, p);
  215: 		if(size != 0)
  216: 		{
  217: 			st = strndup(p, stsize);
  218: 
  219: 			if(st == NULL)
  220: 			{
  221: 				free(url);
  222: 				break;
  223: 			}
  224: 		}
  225: 		p += stsize;
  226: 
  227: 		DECODELENGTH(usnsize, p);
  228: 		if(size != 0)
  229: 		{
  230: 			usn = strndup(p, usnsize);
  231: 
  232: 			if(usn == NULL)
  233: 			{
  234: 				free(url);
  235: 				free(st);
  236: 				break;
  237: 			}
  238: 		}
  239: 		p += usnsize;
  240: 
  241: 		struct UPNPDev *tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize);
  242: 		if(tmp == NULL)
  243: 		{
  244: 			free(url);
  245: 			free(st);
  246: 			free(usn);
  247: 			break;
  248: 		}
  249: 
  250: 		tmp->pNext = devlist;
  251: 		tmp->descURL = tmp->buffer;
  252: 		tmp->st = tmp->buffer + 1 + urlsize;
  253: 		tmp->usn = tmp->buffer + 1 + urlsize + 1 + stsize;
  254: 		memcpy(tmp->descURL, url, urlsize+1);
  255: 		memcpy(tmp->st, st, stsize+1);
  256: 		memcpy(tmp->usn, usn, usnsize+1);
  257: 		free(url);
  258: 		free(st);
  259: 		free(usn);
  260: 		tmp->scope_id = 0;  /* default value. scope_id is not available with MiniSSDPd */
  261: 		devlist = tmp;
  262: 	}
  263: 
  264: 	user_write_cb(stream, us->userdata, devlist);
  265: 	uv_read_stop(stream);
  266: 	stream->data = NULL;
  267: 	free(us);
  268: }
  269: 
  270: void
  271: receiveDevicesFromMiniSSDPD(void *session, void(*requestFinish)(void *session, void *userdata, struct UPNPDev*), void* userdata)
  272: {
  273: 	struct userdata_s *us = malloc(sizeof(struct userdata_s));
  274: 	us->cb = requestFinish;
  275: 	us->userdata = userdata;
  276: 	uv_stream_t *stream = session;
  277: 	stream->data = us;
  278: 	uv_read_start(stream, alloc_cb, read_cb);
  279: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>